自定义属性的构造函数如何采用可选参数

本文关键字:参数 何采用 构造函数 自定义属性 | 更新日期: 2023-09-27 18:32:30

嗨,伙计们,我在互联网上冲浪以获取自定义属性。 我掌握了这个概念,但惊讶和困惑地看到他们通过属性类的构造函数作为参数来设置属性值,该参数没有将任何参数作为构造函数的值。 请澄清核心概念。

[DeBugInfo(45, "Zara Ali", "12/8/2012", **Message = "Return type mismatch"**)]
 //like the Message here.
    public class DeBugInfo : System.Attribute
{
private int bugNo;
private string developer;
private string lastReview;
public string message;
public DeBugInfo(int bg, string dev, string d)
  {
   this.bugNo = bg;
   this.developer = dev;
   this.lastReview = d;
  }
  public int BugNo
 {
 get
 {
 return bugNo;
 }
public string Developer
{
get
{
 return developer;
 }
 }
 public string LastReview
{
get 
{
return lastReview;
}
public string Message
{
 get
{
 return message;
 }
  set
  {
    message = value;
  }
 } 


 //////////////////////////

自定义属性的构造函数如何采用可选参数

属性语法是...与常规 C# 代码略有不同。在常规 C# 中,如果手动创建该对象,则类似于对象初始值设定项:

var obj = new DeBugInfo(45, "Zara Ali", "12/8/2012") {
    Message = "Return type mismatch"
};

但是,实际上,属性并没有以这种方式真正实例化,至少在绝对需要它们之前不会。属性实际上是标记到 IL 中的原始元数据,包括:

  • 构造函数令牌
  • 构造函数的参数,由简单值组成
  • 其他属性/字段分配映射和相应的简单值

您实际上可以检查所有这些信息,而无需实际创建该类型的实例。但是如果你使用 Attribute.GetAttributes etc,它会弄清楚它代表什么,并且基本上在运行时应用构造函数和映射。

有关完整示例:

using System;
class DeBugInfoAttribute : Attribute
{
    public string Message { get; set; }
    public DeBugInfoAttribute(int i, string j, string k)
    {
        // to show we never get here!
        throw new NotImplementedException();
    }
}
[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
static class Program
{
    static void Main()
    {
        // this doesn't create the attribute, so no exception
        foreach (var data in typeof(Program).GetCustomAttributesData())
        {
            Console.WriteLine(data.AttributeType.Name);
            var parameters = data.Constructor.GetParameters();
            int i = 0;
            foreach (var arg in data.ConstructorArguments)
            {
                Console.WriteLine("{0}: {1}",
                    parameters[i++].Name,
                    arg.Value);
            }
            foreach (var binding in data.NamedArguments)
            {
                Console.WriteLine("{0}: {1}",
                    binding.MemberInfo.Name,
                    binding.TypedValue);
            }
        }
        // but this does: BOOM!
        var attribs = Attribute.GetCustomAttributes(typeof(Program));
    }
}