7

有人告诉我,在 c# 中,自动实现的属性不允许使用属性。真的吗?如果是,为什么?

编辑:我从一本流行的 LINQ 书籍中获得了这些信息,简直不敢相信!编辑:请参阅 Paul Kimmel 的 LINQ Unleashed 第 34 页,他说“自动实现的属性不允许使用属性,因此如果需要属性,请自行选择属性

4

5 回答 5

12

您可以毫无问题地将属性应用于自动属性。

引用MSDN

在自动实现的属性上允许使用属性,但显然不允许在支持字段上使用属性,因为这些属性无法从您的源代码中访问。如果您必须在属性的支持字段上使用属性,只需创建一个常规属性。

于 2009-01-21T11:24:05.260 回答
9

证明这是错误的最简单方法是测试它:

using System;
using System.ComponentModel;
using System.Reflection;

class Test
{
    [Description("Auto-implemented property")]
    public static string Foo { get; set; }  

    static void Main(string[] args)
    {
        var property = typeof(Test).GetProperty("Foo");
        var attributes = property.GetCustomAttributes
                (typeof(DescriptionAttribute), false);

        foreach (DescriptionAttribute description in attributes)
        {
            Console.WriteLine(description.Description);
        }
    }
}

我建议您给作者发电子邮件,以便他可以将其作为勘误表发布。如果他的意思是你不能将属性应用到 f ​​ield,这会给他一个更仔细解释的机会。

于 2009-01-21T11:49:58.657 回答
4

我认为作者的意思是,您不能将自定义属性应用于私有支持字段。例如,如果要将自动属性标记为非序列化,则不能这样做:

[Serializable]
public class MyClass
{
    [field:NonSerializedAttribute()]
    public int Id
    {
        get;
        private set;
    }
}

这段代码可以编译,但它不起作用。您可以将属性应用于属性本身,但不能将其应用于支持字段。

于 2010-01-14T15:57:41.927 回答
1

另请注意,任何 Automatic 属性也将应用 CompilerGeneratedAttribute。

于 2009-01-21T11:49:23.743 回答
0

当前版本的 Visual Studio 和 C# 编译器支持这一点。我使用启用了 C# 8.0 的 VS 16.4.2 进行了测试。我不确切知道它是在哪个版本中启用的,但这是个好消息。

句法:

[field: NonSerialized]
public SomeNonSerializableType MyAutoProperty { get; set; } = DefaultValueAfterSerialization;

实际用例;支持整洁/可往返的合格 XML 序列化,没有杂乱的支持字段,但避免运行时异常并解决代码分析错误 CA2235:

/// <summary>
/// XML name table for serialization.
/// </summary
[XmlSerializerNamespaces]
[field: NonSerialized]
public XmlSerializerNamespaces XmlNamespaces { get; set; } = new XmlSerializerNamespaces();

如果您正在使用 .NET Core 3、.NET Standard 2.1 或更高版本开发新的“SDK”样式项目之一,它将立即工作,因为它们默认为语言版本 8。否则对于所有“旧版”.NET Framework 和非-SDK 项目,您必须将“LangVersion”设置添加到您的项目中,如此处所述的“8.0”或“最新”。

于 2020-01-14T14:11:59.710 回答