简体   繁体   English

自动实现的属性是否支持属性?

[英]Do auto-implemented properties support attributes?

I was told that in c# attributes are not allowed on the auto-implemented properties.有人告诉我,在 C# 中,自动实现的属性不允许使用属性。 Is that true?这是真的吗? if so why?如果是为什么?

EDIT: I got this information from a popular book on LINQ and could not believe it!编辑:我从一本关于 LINQ 的流行书中得到了这个信息,简直不敢相信! EDIT: Refer page 34 of LINQ Unleashed by Paul Kimmel where he says " Attributes are not allowed on auto-implemented properties, so roll your own if you need an attribute "编辑:请参阅 Paul Kimmel 的 LINQ Unleashed 的第 34 页,他说“自动实现的属性上不允许使用属性,因此如果需要属性,请使用自己的属性

You can apply attributes to automatic properties without a problem.您可以毫无问题地将特性应用于自动属性。

Quote from MSDN :引用自MSDN

Attributes are permitted on auto-implemented properties but obviously not on the backing fields since those are not accessible from your source code.属性在自动实现的属性上是允许的,但显然不允许在支持字段上,因为这些属性无法从您的源代码中访问。 If you must use an attribute on the backing field of a property, just create a regular property.如果您必须在属性的支持字段上使用属性,只需创建一个常规属性。

The easiest way to prove that's wrong is to just test it:证明这是错误的最简单方法是测试它:

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);
        }
    }
}

I suggest you email the author so he can publish it as an erratum.我建议您给作者发电子邮件,以便他可以将其作为勘误表发布。 If he meant that you can't apply an attribute to the field , this will give him a chance to explain more carefully.如果他的意思是你不能将一个属性应用到领域,这会给他一个更仔细地解释的机会。

I think that author meant, that you can't apply custom attributes to private backing field.我认为作者的意思是,您不能将自定义属性应用于私有支持字段。 For example, if you want to mark automatic property as non serialized, you can't do this:例如,如果要将自动属性标记为非序列化,则不能这样做:

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

This code compiles, but it doesn't work.这段代码可以编译,但不起作用。 You can apply attribute to property itself, but you can't apply it for backing field.可以将属性应用于属性本身,但不能将其应用于支持字段。

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

The current version of Visual Studio and C# compilers support this.当前版本的 Visual Studio 和 C# 编译器支持这一点。 I tested with VS 16.4.2 with C# 8.0 enabled.我在启用 C# 8.0 的情况下使用 VS 16.4.2 进行了测试。 I don't know exactly which version it was enabled in but it's good news.我不知道它在哪个版本中启用,但这是个好消息。

Syntax:语法:

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

Practical use case;实际用例; support neat/round-trip-able qualified XML serialization without messy backing fields but avoid runtime exceptions and resolve code analysis error CA2235:支持整洁/可往返的合格 XML 序列化,无需杂乱的支持字段,但避免运行时异常并解决代码分析错误 CA2235:

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

If you're working on one of the new "SDK" style projects with .NET Core 3, .NET Standard 2.1 or later it will work immediately as they default to language version 8. Otherwise for all "legacy" .NET Framework and non-SDK projects you'll have to add the "LangVersion" setting to your project as documented here to "8.0" or "latest".如果您正在使用 .NET Core 3、.NET Standard 2.1 或更高版本处理新的“SDK”样式项目之一,它将立即工作,因为它们默认为语言版本 8。否则对于所有“遗留”.NET Framework 和非-SDK 项目,您必须将“LangVersion”设置添加到您的项目中,如此处记录的“8.0”或“最新”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM