为什么GetType()在通过方法组委托调用时找不到types?

我们有一个调用Type.GetType静态方法的非常简单的程序。 两个例子都应该返回一个有效的types实例 只有第二个实际上是。 看起来像GetType使用的堆栈爬行有点奇怪,但究竟是什么问题呢? 它是错误还是一些模糊的function?

 public class TestClass { } class Program { static void Main(string[] args) { var fullName = typeof(TestClass).FullName; Console.WriteLine("Full name: {0}", fullName); new[] { fullName }.Select(Type.GetType).ToList().ForEach(t => Console.WriteLine("Method group: '{0}'", t)); new[] { fullName }.Select(t => Type.GetType(t)).ToList().ForEach(t => Console.WriteLine("Closure: '{0}'", t)); } } 

运行:

 Full name: GetTypeBeingWeird.TestClass Method group: '' Closure: 'GetTypeBeingWeird.TestClass' 

这真的很有趣。 它是调用程序集中Type.GetType(string)行为的混合体,以及方法组转换的工作方式。

首先, Type.GetType文档包括:

如果typeName包含名称空间而不包含程序集名称,则此方法将按照该顺序仅search调用对象的程序集和Mscorlib.dll。

在你的第一个调用中,你传入了一个调用Type.GetType的委托,但是它并没有被你的程序集特别调用。 它直接从LINQ中的Select方法调用…如果你从Type.GetType查看堆栈跟踪,我相信你会看到Select作为直接调用者。

在第二次调用中,传递一个调用Type.GetType的闭包,并且该调用在您的程序集中。

这就是为什么它在第二种情况下findtypes,而不是第一种。 这通过指定LINQ程序集中的types进一步validation:

 var fullName = typeof(Enumerable).FullName; 

那么结果是相反的:

 Full name: System.Linq.Enumerable Method group: 'System.Linq.Enumerable' Closure: '' 

如果你在mscorlib中指定了某些东西(比如typeof(string).FullName ),那么这两个方法都是可行的:

 Full name: System.String Method group: 'System.String' Closure: 'System.String' 

在寻找类时仍然使用一个方法组来解决这个问题的方法是简单地提供程序集限定的名称:

 var fullName = typeof(TestClass).AssemblyQualifiedName;