简体   繁体   中英

how the constructor of custom attribute take optional parameters

Hi guys i surf on the internet for custom attributes. i grasp the concept but, surprise and confuse to see that they set properties value through constructor of attribute class as parameter which is not taking any parameter as value from constructor. please clarify the core concept.

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




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

The attribute syntax is ... a bit different to regular C# code. In regular C#, if you were creating that object manually, that would be similar to an object initializer:

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

However, in reality, attributes aren't really instantiated in this way, at least not until they are absolutely required. An attribute is actually raw metadata stamped into the IL, consisting of:

  • a constructor token
  • parameters for the constructor, composed of simple values
  • additional property/field assignment mappings and corresponding simply values

You can actually inspect all this information without ever actually creating an instance of the type. But if you use Attribute.GetAttributes etc, it figures out what it represents, and essentially applies the constructor and mappings at runtime.

For a complete example:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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