[MyAttribute(Name=value)] 中的 "Name=value" 是什么

What is the "Name=value" in [MyAttribute(Name=value)]

我不知道用什么措辞来google这个。

考虑这个属性:

 [MyAttribute(MyOption=true,OtherOption=false)]

Name=value 部分是什么?以及如何在我自己的自定义属性中实现它?

您可以通过声明 public 实例 (non-static) 属性或字段来使用它:

[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
    public string TestValue { get; set; }
}

[My(TestValue = "Hello World!")]
public class MyClass{}

所以它的工作方式几乎与对象初始化器语法相似,但使用 () 而不是 {}


如果您为属性提供带参数的构造函数,则必须先传递参数:

[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
    public string TestValue { get; set; }

    public MyAttribute(int arg)
    {}
}

[My(42, TestValue = "Hello World!")]
public class MyClass{}

C# 规范 17.2 Attribute specification:

An attribute consists of an attribute-name and an optional list of positional and named arguments. The positional arguments (if any) precede the named arguments. A positional argument consists of an attribute-argument-expression; a named argument consists of a name, followed by an equal sign, followed by an attribute-argument-expression, which, together, are constrained by the same rules as simple assignment. The order of named arguments is not significant.

所以这里

[MyAttribute(MyOption=true,OtherOption=false)]

你有两个命名参数。什么是命名参数?同样,C# 规范 17.3.1 Compilation of an attribute:

Name must identify a non-static read-write public field or property on T (attribute type). If T has no such field or property, then a compile-time error occurs.

很清楚,我相信。这些名称或者 non-static public 属性(最有可能)具有 getter 和 setter 或 non-static public 在 MyAttribute 中声明的字段 class:

 public class MyAttribute : Attribute
 {
     public bool MyOption { get; set; }
     public bool OtherOption { get; set; }
 }

如果您需要更多命名参数 - 添加另一个 non-static public read-write 属性 或 non-static public 具有您想要的名称的字段使用。

 public class MyAttribute : Attribute
 {
     public bool MyOption { get; set; }
     public bool OtherOption { get; set; }
     public int Answer { get; set; }
     // public int Answer;  <- another option
 }

用法(顺序无关紧要):

 [MyAttribute(MyOption=true, Answer=42, OtherOption=false)]

它在创建属性实例时指定 属性。

属性可以有构造函数参数和属性 - 这个是设置一个 属性。请注意,您可以混合位置构造函数参数、命名构造函数参数和属性,如下例所示:

using System;
using System.Linq;
using System.Reflection;

[AttributeUsage(AttributeTargets.All)]
public class DemoAttribute : Attribute
{
    public string Property { get; set; }
    public string Ctor1 { get; set; }
    public string Ctor2 { get; set; }
    public string Ctor3 { get; set; }

    public DemoAttribute(string ctor1,
                         string ctor2 = "default2", 
                         string ctor3 = "default3")
    {
        Ctor1 = ctor1;
        Ctor2 = ctor2;
        Ctor3 = ctor3;
    }
}

[Demo("x", ctor3: "y", Property = "z")]
public class Test
{
    static void Main()
    {
        var attr = (DemoAttribute) typeof(Test).GetCustomAttributes(typeof(DemoAttribute)).First();
        Console.WriteLine($"Property: {attr.Property}");
        Console.WriteLine($"Ctor1: {attr.Ctor1}");
        Console.WriteLine($"Ctor2: {attr.Ctor2}");
        Console.WriteLine($"Ctor3: {attr.Ctor3}");
    }
}

注意命名构造函数参数的 : 和 属性 赋值的 = 之间的区别。

这段代码的输出是

Property: z
Ctor1: x
Ctor2: default2
Ctor3: y

不幸的是,在这种情况下,C# 规范同时调用命名构造函数参数和属性 "named arguments":(

这称为属性的命名参数。实际上是属性 class 的 属性。更多信息请访问 https://msdn.microsoft.com/en-us/library/aa288454(v=vs.71).aspx