有人告诉我,在 c# 中,自动实现的属性不允许使用属性。真的吗?如果是,为什么?
编辑:我从一本流行的 LINQ 书籍中获得了这些信息,简直不敢相信!编辑:请参阅 Paul Kimmel 的 LINQ Unleashed 第 34 页,他说“自动实现的属性不允许使用属性,因此如果需要属性,请自行选择属性”
有人告诉我,在 c# 中,自动实现的属性不允许使用属性。真的吗?如果是,为什么?
编辑:我从一本流行的 LINQ 书籍中获得了这些信息,简直不敢相信!编辑:请参阅 Paul Kimmel 的 LINQ Unleashed 第 34 页,他说“自动实现的属性不允许使用属性,因此如果需要属性,请自行选择属性”
您可以毫无问题地将属性应用于自动属性。
引用MSDN:
在自动实现的属性上允许使用属性,但显然不允许在支持字段上使用属性,因为这些属性无法从您的源代码中访问。如果您必须在属性的支持字段上使用属性,只需创建一个常规属性。
证明这是错误的最简单方法是测试它:
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,这会给他一个更仔细解释的机会。
我认为作者的意思是,您不能将自定义属性应用于私有支持字段。例如,如果要将自动属性标记为非序列化,则不能这样做:
[Serializable]
public class MyClass
{
[field:NonSerializedAttribute()]
public int Id
{
get;
private set;
}
}
这段代码可以编译,但它不起作用。您可以将属性应用于属性本身,但不能将其应用于支持字段。
另请注意,任何 Automatic 属性也将应用 CompilerGeneratedAttribute。
当前版本的 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”或“最新”。