大家先想想到底运行后将会出现什么样的结果,看看你的想法和真实的结果是否一致:
对于第二部分基于Named Type的输出,结果很明显,没有什么好说的。我们重点来看基于Anonymous Type的输出结果:
我们通过Inline的方式创建了v1和v2,通过调用定义在另一个Assembly中定义的Utility class创建了v3。虽然我们创建对象的方式不同,但是这3个Instance的结构完全相同,我们可以想象他们对应的Type应该相似。但是,他们到底是不是就是同一个Type呢?通过输出的Type的Full Name:<>f__AnonymousType0`2[System.Guid,System.String]来看,他们“貌似”同一个Type。但是Full name相同并不意味着他们就是同一个Type。确定两个Type的同一性的方法就是确定他们具有相同的Reference。于是我们使用了object.ReferenceEquals方法。两个调用的结果完全不同:v1和v2对应的Type是一样的,而v1和v3则不是同一个。关于Type在Managed Heap的体现,请参阅我的文章: 《[原创]What is "Type" in managed heap?》。
我们来讨论问什么会出现上面的运行结果。原因很简单:Compiler在生成Anonymous Type的时候,并不是为每个形如这样{M1=?, M2 =? , …}的结构生成一个不同的Type,它只会为不同的参数列表的结构:参数的名称,参数的数据类型,参数的相互顺序定义不同的Type。而具有相同的参数列表的{M1=?, M2 =? , …}会共享同一个Type。但是这种机制仅限于在同一个Assembly中。也就是在一个Assembly创建的Anonymous Type仅仅限于在本Assembly中使用,不同被另一个Assembly共享。所以我们通过Inline的方式创建了v1和v2是同一个Type的两个Instance,而我们通过跨Assembly创建的v3却属于不同的Type,尽管他们的Type定义可能完全一样。

