我是C#的初学者,我的教科书上说“匿名类型”不能有字段,只能有属性,例如:
var myAnonymousType = new {
firstProperty = "First",
secondProperty = 2,
thirdProperty = true
};
但不是某个属性应具有以下特征:
public string firstProperty { get; }
还是编译器确实为我添加了它?
答案 0 :(得分:1)
您几乎是正确的。如果您编译代码并使用ILDASM之类的IL反汇编程序,则会注意到创建了这样的类来表示您的匿名类型:
class AnonymoutType
{
private string _firstProperty;
public string firstProperty { get { return _firstProperty; }
private string _secondProperty;
public int secondProperty { get { return _secondProperty; }
private string _thirdProperty;
public bool thirdProperty { get { return _thirdProperty; }
public AnonymoutType(string firstProperty, int secondProperty, bool thirdProperty)
{
_firstProperty = firstProperty;
_secondProperty = secondProperty;
_thirdProperty = thirdProperty;
}
}
名称在IL代码中将与上面的名称不同,但请注意,该类的属性没有设置器。他们初始化的唯一方法是通过类的构造函数。因此,当您编写以下内容时:
var myAnonymousType = new {
firstProperty = "First",
secondProperty = 2,
thirdProperty = true
};
在运行时(执行程序时)将创建AnonymousType
类的实例,如下所示:
var myAnonymousType = new AnonymoutTypes("First", 2, true);
下面我附上了带有IL代码的屏幕截图:
答案 1 :(得分:0)
您的代码
var myAnonymousType = new {
firstProperty = "First",
secondProperty = 2,
thirdProperty = true
};
与
相似class YourClass{
public string firstProperty { get; set; }
public int secondProperty { get; set; }
public bool thirdProperty { get; set; }
}
答案 2 :(得分:0)
根据此链接:
https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/anonymous-types
匿名类型是只读的,不能设置。它们通常在select子句中使用。
匿名类型包含一个或多个公共只读属性。
因此,您的代码:
var myAnonymousType = new {
firstProperty = "First",
secondProperty = 2,
thirdProperty = true
};
更像这样:
class myAnonymousType
{
firstProperty {get;}
secondProperty {get;}
thirdProperty {get;}
}
这是一个有趣的链接:
https://blogs.msdn.microsoft.com/miah/2007/09/07/overcoming-the-limitations-of-anonymous-types/
答案 3 :(得分:-1)
这是编译器的诡计。
这是您的代码:
var myAnonymousType = new
{
firstProperty = "First",
secondProperty = 2,
thirdProperty = true
};
这是生成的类:
[CompilerGenerated]
[DebuggerDisplay("\\{ firstProperty = {firstProperty}, secondProperty = {secondProperty}, thirdProperty = {thirdProperty} }", Type = "<Anonymous Type>")]
internal sealed class <>f__AnonymousType0<<firstProperty>j__TPar, <secondProperty>j__TPar, <thirdProperty>j__TPar>
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly <firstProperty>j__TPar <firstProperty>i__Field;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly <secondProperty>j__TPar <secondProperty>i__Field;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly <thirdProperty>j__TPar <thirdProperty>i__Field;
public <firstProperty>j__TPar firstProperty
{
get
{
return <firstProperty>i__Field;
}
}
public <secondProperty>j__TPar secondProperty
{
get
{
return <secondProperty>i__Field;
}
}
public <thirdProperty>j__TPar thirdProperty
{
get
{
return <thirdProperty>i__Field;
}
}
[DebuggerHidden]
public <>f__AnonymousType0(<firstProperty>j__TPar firstProperty, <secondProperty>j__TPar secondProperty, <thirdProperty>j__TPar thirdProperty)
{
<firstProperty>i__Field = firstProperty;
<secondProperty>i__Field = secondProperty;
<thirdProperty>i__Field = thirdProperty;
}
[DebuggerHidden]
public override bool Equals(object value)
{
<>f__AnonymousType0<<firstProperty>j__TPar, <secondProperty>j__TPar, <thirdProperty>j__TPar> anon = value as <>f__AnonymousType0<<firstProperty>j__TPar, <secondProperty>j__TPar, <thirdProperty>j__TPar>;
return anon != null && EqualityComparer<<firstProperty>j__TPar>.Default.Equals(<firstProperty>i__Field, anon.<firstProperty>i__Field) && EqualityComparer<<secondProperty>j__TPar>.Default.Equals(<secondProperty>i__Field, anon.<secondProperty>i__Field) && EqualityComparer<<thirdProperty>j__TPar>.Default.Equals(<thirdProperty>i__Field, anon.<thirdProperty>i__Field);
}
[DebuggerHidden]
public override int GetHashCode()
{
return ((1541079692 * -1521134295 + EqualityComparer<<firstProperty>j__TPar>.Default.GetHashCode(<firstProperty>i__Field)) * -1521134295 + EqualityComparer<<secondProperty>j__TPar>.Default.GetHashCode(<secondProperty>i__Field)) * -1521134295 + EqualityComparer<<thirdProperty>j__TPar>.Default.GetHashCode(<thirdProperty>i__Field);
}
[DebuggerHidden]
public override string ToString()
{
object[] obj = new object[3];
<firstProperty>j__TPar val = <firstProperty>i__Field;
ref <firstProperty>j__TPar reference = ref val;
<firstProperty>j__TPar val2 = default(<firstProperty>j__TPar);
object obj2;
if (val2 == null)
{
val2 = reference;
reference = ref val2;
if (val2 == null)
{
obj2 = null;
goto IL_0046;
}
}
obj2 = reference.ToString();
goto IL_0046;
IL_0081:
object obj3;
obj[1] = obj3;
<thirdProperty>j__TPar val3 = <thirdProperty>i__Field;
ref <thirdProperty>j__TPar reference2 = ref val3;
<thirdProperty>j__TPar val4 = default(<thirdProperty>j__TPar);
object obj4;
if (val4 == null)
{
val4 = reference2;
reference2 = ref val4;
if (val4 == null)
{
obj4 = null;
goto IL_00c0;
}
}
obj4 = reference2.ToString();
goto IL_00c0;
IL_00c0:
obj[2] = obj4;
return string.Format(null, "{{ firstProperty = {0}, secondProperty = {1}, thirdProperty = {2} }}", obj);
IL_0046:
obj[0] = obj2;
<secondProperty>j__TPar val5 = <secondProperty>i__Field;
ref <secondProperty>j__TPar reference3 = ref val5;
<secondProperty>j__TPar val6 = default(<secondProperty>j__TPar);
if (val6 == null)
{
val6 = reference3;
reference3 = ref val6;
if (val6 == null)
{
obj3 = null;
goto IL_0081;
}
}
obj3 = reference3.ToString();
goto IL_0081;
}
}