C#不指定类型的泛型方法

C#不指定类型的泛型方法,c#,.net,generics,.net-3.5,generic-method,C#,.net,Generics,.net 3.5,Generic Method,好的,我是一个Java的家伙,开始使用C#,我编写并开始制作一个泛型方法,我编写的运行和编译,但这与我所知道的关于泛型应该如何工作的一切都背道而驰,所以我希望有人能给我解释一下: 因此,我有一个通用方法,定义如下: public static List<T> CopyAsList<T>(IEnumerable<T> list, Object lockObject) { if (list != null) { lo

好的,我是一个Java的家伙,开始使用C#,我编写并开始制作一个泛型方法,我编写的运行和编译,但这与我所知道的关于泛型应该如何工作的一切都背道而驰,所以我希望有人能给我解释一下:

因此,我有一个通用方法,定义如下:

public static List<T> CopyAsList<T>(IEnumerable<T> list, Object lockObject)  
{  
    if (list != null)  
    {  
        lock (lockObject)  
        {  
            return new List<T>(list);  
        }  
    }  
    return null;  
}  

代码如何能够在不指定泛型类型的情况下进行编译?C#是否在运行时推断类型?

否,它是在编译时推断的-使用您提供的
IEnumerable
中的泛型类型参数,这在编译时是已知的。一般来说,关于泛型和类型参数的所有内容都是在编译时指定的。如果存在任何类型的不匹配,编译器将投诉,并且您的代码将无法编译

在一些边缘情况下,您必须显式指定类型,这些情况仅在重载方法的少数情况下发生,有时使用多个类型参数组合。

C编译器通常可以在编译时推断泛型类型。当它可以做到这一点时,您不需要为泛型方法指定类型

这是使LINQ“可用”的主要部分。如果没有编译时类型推断,查询将如下所示:

IEnumerable<int> myIds = myCollection
                             .Where<MyType>(i => i.Name == "Foo")
                             .Select<MyType, int>(i => i.Id);

C#比Java具有多得多的编译时和运行时类型推断功能。如果您对这个主题感兴趣,请参阅我关于这个主题的文章:

如果您对泛型方法类型推断特别感兴趣,并且您还有半个小时的时间,下面我将解释我们如何在C#3中更改类型推断算法:


匿名类型的查询将是不可能的,而且,如果编译器无法推断出类型,代码将无法编译。如果没有类型推断,编译器也不会知道那些lambda将拥有什么类型。运行时不再有C。C编译器在编译时推断出类型。另一方面,CLR(DLR)可以在运行时推断类型,请参见C#kizzx2中的
dynamic
关键字:OP使用
.net-3.5
标记问题,这将从上下文中消除
dynamic
,并且在运行时没有类型推断——DLR使用反射来确定类型。“运行时类型推断功能”你在说什么功能?与
dynamic
相关的东西?@CodeInChaos:是的,在C#中,“dynamic”的意思是“在运行时,而不是在编译时对这个表达式进行类型分析”。我知道
dynamic
的作用。我只是想知道,您是否在谈论
动态
功能之外的运行时类型推断。其中一种情况是,方法的任何参数都是动态类型的-一旦您将其放入其中,所有编译器泛型类型推断都将消失,即使存在所有相同的线索。
IEnumerable<int> myIds = myCollection
                             .Where<MyType>(i => i.Name == "Foo")
                             .Select<MyType, int>(i => i.Id);
var myIds = myCollection.Where(i => i.Name == "Foo").Select(i => i.Id);