我正在搞乱匿名类型,我不小心将它输出到控制台上。它看起来基本上是我如何定义它。
这是一个重现它的简短程序:
using System;
class Program
{
public static void Main(string[] args)
{
int Integer = 2;
DateTime DateTime = DateTime.Now;
Console.WriteLine(new { Test = 0, Integer, s = DateTime });
Console.ReadKey(true);
}
}
现在,输出是:
{ Test = 0, Integer = 2, s = 28/05/2013 15:07:19 }
我尝试使用dotPeek进入程序集找出原因,但没有帮助。 [1] 这是dotPeek'd代码:
// Type: Program
// Assembly: MyProjectName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// Assembly location: Not telling you! :P
using System;
internal class Program
{
public static void Main(string[] args)
{
Console.WriteLine((object) new
{
Test = 0,
Integer = 2,
s = DateTime.Now
});
Console.ReadKey(true);
}
}
所以没有太大的不同。
那它是如何运作的?它如何输出呢?
注意:
[1] :我忘了打开“显示编译器生成的代码”,这就是我没有得到它如何工作的原因。
答案 0 :(得分:15)
使用匿名对象......
编译器生成一个内部密封类,用于对其进行建模 匿名类型。匿名类型是不可变的;所有的属性 是只读的。该类包含Equals()和的覆盖 实现值语义的GetHashCode()。除此之外 编译器生成一个显示值的ToString()重写 每个公共财产。
来源:link
请检查 @Ilya Ivanov ,以查看有关此主题的一些代码。
答案 1 :(得分:15)
只是为HuorSwords答案添加一些代码,编译器将为您的示例生成 ToString
方法,如下所示:
public override string ToString()
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("{ Test = ");
stringBuilder.Append((object) this.<Test>__Field);
stringBuilder.Append(", Integer = ");
stringBuilder.Append((object) this.<Integer>__Field);
stringBuilder.Append(", s = ");
stringBuilder.Append((object) this.<s>__Field);
stringBuilder.Append(" }");
return ((object) stringBuilder).ToString();
}
如果在编译时拥有所有必需的元数据,那么在这里使用反射效率会很低。
使用 dotPeek 进行反编译,此版本可能会因使用的反编译器而异。
注意:由于您还使用dotPeek进行反编译,请尝试查看 Root Namespace 。你会在那里找到类似的东西:
[DebuggerDisplay("\\{ Test = {Test}, Integer = {Integer}, s = {s} }", Type = "<Anonymous Type>")]
internal sealed class <>__AnonymousType0<<Test>
这是您在定义匿名对象时生成的内容的示例。
答案 2 :(得分:9)
匿名类型仍然是完全定义的类型......简单地说:编译器完全自己生成它们,你永远不会看到名称/实现(只是:它匹配你在代码中使用的初始化程序)。
实际上,关于特定操作中的匿名类型,ToString
未提及(第7.6.10.6节);只有必需 Equals
和GetHashCode
才能在属性方面发挥作用。规范中的示例(“声明表单的匿名类型”) 不 包含ToString
覆盖。
MS编译器将ToString
的基于属性的实现添加为一个有礼貌的 - 但也可能是因为默认 ToString
是类型名称,这本身就没有意义(毕竟,它是匿名的 - 类型名称读起来非常可怕,并且包含泛型语法)。坦率地说,仅将其用于调试目的是个好主意。