About the attribute feature in C #

Source: Internet
Author: User
Tags bitwise

Absrtact: This should be considered as a note about attribute, some of the ideas and codes that draw on others ' writing (see the link at the bottom of this article). However, because this article on attribute is really applauded (boasting about ^_^), so the public, hope to be helpful to everyone.

  The difference of translation between attribute and property

Attribute the general translation "Properties", the property is still translated as "attributes".

  What is Attribute?

Attribute is a user-definable modifier (Modifier) that can be used to modify a variety of targets that need to be modified.

Simply put, attribute is an "attachment"-just like an oyster adsorbed on a ship or reef.

The effect of these attachments is to append additional information to their attachment (which is stored in the body of the attachment)-for example, "This class is what I wrote" or "This function has had problems before" and so on.

  The role of Attribute

The role of attribute attribute is to add metadata.
Meta data can be supported by tools such as compiling with metadata to debug programs with meta data.

  The difference between Attribute and annotations

    • Note is a description of the program source code, the main purpose is to show people, when the program is compiled by the compiler will be discarded, so it does not affect the execution of the program.
    • and attribute is part of the program code, not only will not be discarded by the compiler, but also by the compiler compiled into the assembly (Assembly) metadata (Metadata), when the program runs, you can always extract the metadata from the meta-data to the operation of the decision-making program.

Example:

In the project, there is a class that is maintained by two programmers (Xiao Zhang and Xiao Li). This class acts as a "toolkit" (like the math class in the. NET framework), which contains dozens of static methods (Utilities). And these static methods, half of which are written by Xiao Zhang, and half are written by Xiao Li; in the test of the project, there were some static methods that had been bugs and were later fixed. In this way, we can divide these aspects into such categories as:

The main purpose of our classification is to test in different categories and get different effects when testing. For example: Statistics two people's workload or the method that has been out of the bug regression test.

If you do not use attribute, in order to distinguish the four static methods, we can only be explained by comments, but this way there are many drawbacks;

If you use attribute, it will be much easier to differentiate between these four static methods. The sample code is as follows:

#define Buged
The macro definition for C # must appear before all code. Only buged macros are currently valid.
Using System;
Using System.Diagnostics; Note: This is to use the ConditionalAttribute attribute contained in this namespace
Namespace Con_attribute
{
Class Program
{
static void Main (string[] args)
{
Although the methods are called, only the qualifying ones will be executed!
Toolkit.funa ();
Toolkit.funb ();
Toolkit.func ();
Toolkit.fund ();
}
}
Class ToolKit
{
[ConditionalAttribute ("Li")]//attribute the name of the long notation
[ConditionalAttribute ("buged")]
public static void Funa ()
{
Console.WriteLine ("Created by Li, buged.");
}
[Conditional ("Li")]//attribute the name of the short notation
[Conditional ("Nobug")]
public static void Funb ()
{
Console.WriteLine ("Created by Li, Nobug.");
}
[ConditionalAttribute ("Zhang")]//attribute name of the long notation
[ConditionalAttribute ("buged")]
public static void FunC ()
{
Console.WriteLine ("Created by Zhang, buged.");
}
[Conditional ("Zhang")]//attribute the name of the short notation
[Conditional ("Nobug")]
public static void FunD ()
{
Console.WriteLine ("Created by Zhang, Nobug.");
}
}
}

The results of the operation are as follows:

Note: The result of the run is determined by the macro definition "#define buged" in the code.

Analysis:

1. In this example, we used the ConditionalAttribute attribute, which is included in the System.Diagnostics namespace. Obviously, it is most of the time to do program debugging and diagnosis.

2. Related to ConditionalAttribute is a set of C # macros that look like the C-language macro indistinguishable, and the location must appear before all C # code. As the name implies, ConditionalAttribute is used to judge the conditions, where the conditionalattribute (or conditional) "attached" to the method, only meet the conditions will be executed.

3. Attribute Like many oysters can be attached to the bottom of a ship, a method can also attach multiple instances of ConditionalAttribute. attribute attached to the target of the writing format is very simple, using square brackets around the attribute, and then write the attribute attached to the line. When multiple attribute are attached to the same target, the square brackets of these attribute are written one by one (or multiple attribute in one square bracket), and do not care about their order.

4. When using attribute, there are two kinds of "long notation" and "short notation", please help yourself.

By the above 3rd and 4th we can launch, the following four kinds of attribute are used in a completely equivalent way:

Long Kee Method
[ConditionalAttribute ("LI")]
[ConditionalAttribute ("Nobug")]
public static void Fun ()
{Console.WriteLine ("Created by Li, Nobug.");
Short notation
[Conditional ("LI")]
[Conditional ("Nobug")]
public static void Fun ()
{Console.WriteLine ("Created by Li, Nobug.");
Change Order
[Conditional ("Nobug")]
[Conditional ("LI")]
public static void Fun ()
{Console.WriteLine ("Created by Li, Nobug.");
Single Bracket Overlay
[Conditional ("Nobug"), Conditional ("LI")]
public static void Fun ()
{Console.WriteLine ("Created by Li, Nobug.");

  The essence of Attribute

From the above code, we can see that attribute always appears to be with public, static these keywords (Keyword) appear together.

Is it the equivalent of defining a new modifier (Modifier) using attribute? Let's get a glimpse of what's going on!

The sample code is as follows:

#define XG//c# macro definition must appear before all code
Using System;
Using System.Diagnostics; Note: This is to use the ConditionalAttribute attribute contained in this namespace
Namespace Con_attribute
{
Class Program2
{
[Conditional ("XG")]
static void Fun ()
{
Console.foregroundcolor = Consolecolor.yellow;
Console.WriteLine ("Http://xugang.cnblogs.com");
}
static void Main (string[] args)
{
Fun ();
}
}
}

Use the Microsoft intermediate Language Anti-compiler to view the code for the Targetmethod:void () method in the MSIL intermediate language, as follows:

As you can see: Attribute is essentially a class that is eventually instantiated on the attached target object.

After careful observation of the Code in the intermediate language (MSIL), the fact that is obscured by the C # language becomes naked in the intermediate language (MSIL). and attribute has become no secret!

The red in the figure refers to the fun method and its modifiers, but attribute does not appear here.

The blue in the figure refers to the constructor of the ConditionalAttribute class in the System.Diagnostics namespace in the calling mscorlib.dll assembly.

Visible, Attribute is not a modifier, but a class with a unique instantiation form!

  What's so unique about Attribute instantiation?

1. Its instance is declared with the. Custom declaration. Looking at the intermediate language syntax, you will find that. Custom is specifically used to declare custom attributes.

2. Declare the location of attribute before the real code in the body of the function (il_0000 to il_0014).

This proves from the "bottom" that attribute is not a "modifier", but rather a class that is instantiated in a more specific way.

  The role of Meta data

In the MSIL intermediate language, the assembly's metadata (Metadata) records how many namespace in the assembly, how many classes, what members are in the class, and what level of access the Members have. Also, metadata is used in the form of text (that is, Unicode characters). NET reflection (Reflection) technology can read them out and form the tree in MSIL, the object Browser view in VS, and the automatic code hinting function, which is the product of the combination of meta-data and reflection technology. An assembly (. EXE or. DLL) can fully describe itself using metadata contained within its own body, rather than having a large bundle of headers, such as a C + +, called "self-contained" or "self-descriptive."

  Instantiation of the Attribute

Just as oysters are born to be adsorbed on reefs or on the bottom of a ship, the example of Attribute must be "glued" to a target when it is constructed.

The syntax of Attribute instantiation is rather bizarre, mainly embodied in the following three points:

1. Instead of using the new operator to produce an instance, use the constructor in square brackets to generate the instance.

2. Square brackets must be placed immediately before the attached target.

3. Because space is limited in square brackets, you cannot construct the object as you would with new, and then assign a value to the object's property.

Therefore, the property assignment to the attribute instance is also in the parentheses of the constructor.

Also, the Attribute instantiation is especially important to note:

1. The parameters of the constructor must be written. A few will have to write a few, because if you do not write instances can not be constructed.

2. Constructor parameters cannot be ordered in the wrong order. Calling any function cannot change the order of the arguments unless it has a corresponding overload (overload). Because this order is fixed, some books call it "positional parameters" (meaning "number and position fixed parameters").

3. Assigning an attribute to a attribute instance is optional. Anyway, it will have a default value, and the order of the property assignments is unrestricted. In some books, the parameter called attribute assignment is named parameter.

  customizing attribute instances

Here, instead of using the various attribute system features in the. NET Framework, we are customizing a completely new attribute class from scratch.

The sample code is as follows:

Using System;
Namespace Con_attribute
{
Class Program3
{
static void Main (string[] args)
{
Reading attribute with Reflection
System.Reflection.MemberInfo info = typeof (Student); Get the information of student class by reflection
Hobby hobbyattr = (Hobby) Attribute.GetCustomAttribute (info, typeof (Hobby));
if (hobbyattr! = null)
{
Console.WriteLine ("Class name: {0}", info.) Name);
Console.WriteLine ("Interest type: {0}", Hobbyattr.type);
Console.WriteLine ("Interest Index: {0}", Hobbyattr.level);
}
}
}
Note: "Sports" is the assignment to the constructor, level = 5 is the assignment to the property.
[Hobby ("Sports", Level = 5)]
Class Student
{
[Hobby ("Football")]
public string profession;
public string Profession
{
get {return profession;}
set {profession = value;}
}
}
Suggested Name: Hobbyattribute
Class Hobby:attribute//Must be based on System.Attribute classes
{
A string with a null parameter value is dangerous, so it is necessary to assign a value in the constructor
Public Hobby (String _type)//positional parameters
{
This.type = _type;
}
Type of Interest
private string type;
public string Type
{
get {return type;}
set {type = value;}
}
Interest Index
private int level;
public int Level
{
get {return level;}
set {level = value;}
}
}
}

To keep the code from being too long, the constructor for the hobby class in the example above has only one parameter, so the "positional parameters" are not enough. You can add a few more properties to the Hobby class and set up several parameters in the constructor to experience the sensitivity of the number of parameters and the position of the parameter in the attribute instantiation.

  A target that can be attached by attribute.

Attribute can you attach your own instance to what target? The answer to this question is hidden in the enumeration type AttributeTargets.

The set of desirable values for this type is:

All Assembly Class Constructor

delegate                            enum                                 event                                Field

Genericparameter Interface Method Module

Parameter Property ReturnValue Struct

There are altogether 16 desirable values. The above table is arranged alphabetically, and does not represent the order in which their true values are arranged.

Use this applet to see the integer value corresponding to each enumeration value, as shown in the following example code:

Using System;
Namespace Con_attribute
{
Class Program4
{
static void Main (string[] args)
{
Console.WriteLine ("Assembly\t\t\t{0}", Convert.ToInt32 (attributetargets.assembly));
Console.WriteLine ("Module\t\t\t\t{0}", Convert.ToInt32 (AttributeTargets.Module));
Console.WriteLine ("Class\t\t\t\t{0}", Convert.ToInt32 (AttributeTargets.Class));
Console.WriteLine ("Struct\t\t\t\t{0}", Convert.ToInt32 (attributetargets.struct));
Console.WriteLine ("Enum\t\t\t\t{0}", Convert.ToInt32 (Attributetargets.enum));
Console.WriteLine ("Constructor\t\t\t{0}", Convert.ToInt32 (Attributetargets.constructor));
Console.WriteLine ("Method\t\t\t\t{0}", Convert.ToInt32 (AttributeTargets.Method));
Console.WriteLine ("Property\t\t\t{0}", Convert.ToInt32 (Attributetargets.property));
Console.WriteLine ("Field\t\t\t\t{0}", Convert.ToInt32 (Attributetargets.field));
Console.WriteLine ("Event\t\t\t\t{0}", Convert.ToInt32 (attributetargets.event));
Console.WriteLine ("Interface\t\t\t{0}", Convert.ToInt32 (Attributetargets.interface));
Console.WriteLine ("Parameter\t\t\t{0}", Convert.ToInt32 (Attributetargets.parameter));
Console.WriteLine ("Delegate\t\t\t{0}", Convert.ToInt32 (attributetargets.delegate));
Console.WriteLine ("Returnvalue\t\t\t{0}", Convert.ToInt32 (Attributetargets.returnvalue));
Console.WriteLine ("Genericparameter\t\t{0}", Convert.ToInt32 (Attributetargets.genericparameter));
Console.WriteLine ("All\t\t\t\t{0}", Convert.ToInt32 (AttributeTargets.All));
Console.WriteLine ("\ n");
}
}
}

The results are shown below:

AttributeTargets uses another usage of the enumeration value-the identity bit.
In addition to the value of all, only one of the binary forms of each value is "1" and the remaining bits are all "0".
If our attribute requirements can be both attached to the class and attached to the method of the class. You can use the operator ' | ' in C # (That is, bitwise "or"). With it, we just need to write the code as follows:

AttributeTargets.Class | AttributeTargets.Method

Because the identity bits of the two enumeration values (that is, the only "1") are staggered, you only need to bitwise or solve the problem.

In this way, you can understand: why the value of AttributeTargets.All is 32767.

By default, when we declare and define a new attribute class, its attachment target is attributetargets.all.

In most cases, the AttributeTargets.All has already met the requirements. However, if you have to limit it, it will be a bit of a struggle.

For example, if you want to limit the attachment target of the preceding hobby class to only "class" and "field", the sample code is as follows:

[AttributeUsage (AttributeTargets.Class, Attributetargets.field)]
Class Hobby:attribute//Must be based on System.Attribute classes
{
Concrete implementation of Hobby class
}

Here is an instance of using attribute (AttributeUsage) attached to the attribute Class (Hobby). The essence of Attribute is the class, and AttributeUsage shows which types the hobby class can attach to.

Additional questions:

1. If a attribute class is attached to a class, will the attribute class be attached to the derived class with the inheritance relationship?

2. Is it possible to have multiple instances of a attribute class attached to the same target as multiple oysters are attached to the same ship?

Answer: Yes. The code is as follows:

[AttributeUsage (AttributeTargets.Class | Attributetargets.field, inherited = False, AllowMultiple = True)]
Class Hobby:System.Attribute
{
Concrete implementation of Hobby class
}

AttributeUsage, a attribute specifically designed to modify attribute, can also determine whether the attribute it modifies can be "inherited" with the host, and whether multiple instances can be used to decorate the same target, in addition to modifying the target.

What is the AttributeUsage that modifies ConditionalAttribute? (The answer is on MSDN)

Reference Source:

Application of Attribute in. NET programming

]--attribute experience in attribute[

On the essence of]--attribute in attribute[

Sample code

(go) about the attribute feature in C #

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.