当前位置: 代码迷 >> C# >> C#的匿名类型的门类信息是保存在哪里,Type似乎可以重名啊
  详细解决方案

C#的匿名类型的门类信息是保存在哪里,Type似乎可以重名啊

热度:84   发布时间:2016-05-05 03:24:33.0
C#的匿名类型的类型信息是保存在哪里,Type似乎可以重名啊?
例如,我定义了一个ClassLibrary,代码如下(代码里面没有namespace)

public class ClassLibrary1
{
    public static void f()
    {
        var m = new { m_s = "abc", m_l = 2L };
        Console.WriteLine(m.GetType());
    }
}

然后我建立一个控制台程序,加入对ClassLibrary1的引用,主程序代码如下:(注意,也是没有namespace)

class Program
{
    static void Main()
    {
        var m = new {m_s = "xyz", m_l = 5L};
        Console.WriteLine(m.GetType());
        ClassLibrary1.f();
    }
}

运行主程序,我得到如下的输出:
<>f__AnonymousType0`2[System.String,System.Int64]
<>f__AnonymousType0`2[System.String,System.Int64]
Press any key to continue . . .

也就是说,dll当中的匿名类和exe当中的匿名类,其类型信息可以一样。
我就奇怪了,如果.net的2进制内容把类型信息存在一个全局的地方,如何能避免重名呢? 注意到我没有使用namespace

况且,程序在启动的时候,如何判断某条语句到底是用的哪一个类型信息来创建对象呢?
------解决思路----------------------
微软的实际实现没真的研究过,不过我做动态创建类型的时候,通常会将根据一些特征作为key。
当前你这个匿名类型来说,2个属性的名称和类型是完全一致的。相当于把你的属性信息作为key,第一次把创建的类型保存下来,下次遇到同key的情形,就直接使用已有的类型。
伪代码可以如下:

Hash<key,Type> hash=new Hash<key,Type>();
pubilc Type GetNamelessType(PropertyInfo[] p)
{
 key=MD5(p);
Type t=null;
if(Hash.TryGetValue(key, out t))
{
return t;
}
else
{
t=CreateType(p);
Hash.Add(key,t);
return t;
}
}
------解决思路----------------------
引用:
类型信息一样,又有什么坏处呢?
其实不仅类型信息,类型也一样,这样还能避免重复定义类型,减少assembly的大小。


以下是C#语言规范“7.6.10.6 Anonymous object creation expressions"的例子和解释:
CSharp Language Specification
In the example
    var p1 = new { Name = "Lawnmower", Price = 495.00 };
    var p2 = new { Name = "Shovel", Price = 26.95 };
    p1 = p2;
the assignment on the last line is permitted because p1 and p2 are of the same anonymous type.

中文翻译就是:p1和p2具有相同的匿名类型,因此p2可以赋值给p1。

至于”C#的匿名类型的类型信息是保存在那里“,它同样保存在assembly里,只不过不用你自己写类型代码,编译器帮你生成而已。
------解决思路----------------------
匿名类型(C# 编程指南)
中明确的说到:虽然你的应用程序不能访问它,编译器还是提供了每一个匿名类型的名称。 从公共语言运行时的角度来看,匿名类型与任何其他引用类型没有什么不同。
所以你耽心冲突的顾虑是不必要的
  相关解决方案