C#匿名类型中仅允许使用的属性

时间:2019-02-12 05:40:10

标签: c#

我是C#的初学者,我的教科书上说“匿名类型”不能有字段,只能有属性,例如:

var myAnonymousType = new { 
    firstProperty = "First", 
    secondProperty = 2, 
    thirdProperty = true 
};

但不是某个属性应具有以下特征:

public string firstProperty { get; }

还是编译器确实为我添加了它?

4 个答案:

答案 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代码的屏幕截图:

enter image description here

答案 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;
    }
}