Custom Attributes
Before you say a custom, it is necessary to introduce some basic concepts.
Metadata: Some classes encapsulated in C # that cannot be modified, the attributes of a class member are referred to as annotations in the metadata
1. What are features?
(1) Differences in attributes and properties
Property: A property is an object-oriented idea that encapsulates a data field within a class, Get,set method.
Attribute: Equivalent to the metadata of the class.
To see the official explanation?
An attribute is an additional declarative information that is given to a specified declaration. A description declaration that allows similar keywords. It labels the elements in the program, such as types, fields, methods, properties, and so on. From the. NET perspective, attributes are classes that inherit from the System.Attribute class and are used to describe classes, properties, methods, events, and so on, primarily in reflection. But from an object-oriented level, attribute is actually a type-level, not an object-level.
The metadata for attribute and. net files is saved together, and can be used to describe your code to the runtime, or to affect the program's behavior when the program is running.
2. Application of features
(1). NET attributes are used to handle a variety of problems, such as serialization, the security characteristics of the program, to prevent the immediate compiler to optimize the program code and so the code is easy to debug and so on. The nature of the value-setting attribute is to add additional information on the elements of a class and run it through reflection with that additional information ( Often used when working with data entity objects)
(2) Application of attribute as a compile-time instruction
Conditional the role of conditional compilation, only if the condition is met, the compiler is allowed to compile its code. Generally used when debugging the program.
DllImport: Used to mark a non-. NET function, indicating that the method is defined in an external DLL.
Obsolete: This property is used to mark that the current method has been deprecated and is no longer used.
Note: attribute is a class, so DllImport is also a class, and the attribute class is instantiated at compile time, rather than being instantiated at run time as usual.
CLSCompliant: Ensure that the entire assembly code complies with the CLS, otherwise the compilation will error.
3. Custom Features
Use AttributeUsage to control how the newly defined attributes are applied.
[AttributeUsageAttribute (AttributeTargets.All can be applied to any element
, Allowmultiple=true, allows the application to be repeated multiple times, and our fixed-value feature can be duplicated several times before the same program entity.
, Inherited=false, do not inherit to derived
)]
The attribute is also a class that must inherit from the System.Attribute class, the naming specification of my class name +attribute. Whether directly or indirectly, inheritance is an attribute class, and the declaration of an attribute class defines a new attribute that can be placed on top of the declaration. Use the [] syntax for custom attributes, You can use reflection to view your custom attributes.
Case:
public class MyselfAttribute:System.Attribute
But to be honest, features are often used, but custom features are almost impossible to use, seemingly foreigners like to use.
If you cannot define an attribute and use it, my last name you must think I am bluffing you, suppose we have such a very common need: when we create or update a class file, we need to say when to this class when, who created, in a row of updates also to explain when who updated, You can record or not record the content of the update, what will you do in the past? You must have thought of it. Add Comments:
Updated: Zhang San, 2015-2-3, modified the ToString () method
Updated: John Doe, 2014-4-5
Created: Harry, 2011-7-8
public class DemoClass
{
DoSomething
}
This does not matter, want what, write what, looks very good ah, borrow Venus Teacher's sentence is perfect!
But what if we had one day trying to keep these records in the database as a backup? Do you want to go through the source file, find out the comments, and insert them into the database in a single line?
With the definition of the above attribute, we know that attributes can be used to add metadata to a type (a description of how the data is felt, including whether the data has been modified, when it was created, and who created it, which can be a class, method, attribute) that can be used to describe the type. In this case, the feature will come in handy. The metadata should be: Comment type (more or less), modify person, date, note information (optional). The target type of the attribute is the Democlass class.
By understanding the metadata attached to the Democlass class, we first create a class that encapsulates the metadata:
public class Recordattribute
{
Private string recordtype;//record type: Update or create
private string author;//author
Private DateTime data;//Date
private string memo;//remarks
The parameters of the constructor are also called positional parameters in the attribute.
Public Recordattribute (String recordtype,string author,string date)
{
This.recordtype = RecordType;
This.author = author;
This.data = convert.todatetime (date);
}
For positional parameters, usually only get access is provided
public string RecordType {get {return recordtype;}}
public string Author {get {return Author;}}
Public DateTime Date {get {return Date;}}
Build an attribute, also called a named parameter in the attribute
public string Memo {
get {return memo;}
set {memo = value;}
}
}
Note: The parameter of the constructor, date, must be a constant, type, or constant array, so the DateTime type cannot be passed directly.
Would you say that this is not a class? You can't turn into a trait because you follow a attribute. So then can he become a trait and apply it to a class? Before we go to the next step, let's take a look at how the. NET Built-in feature obsolete is defined:
Namespace System {
[Serializable]
[AttributeUsage (6140, inherited = False)]
[ComVisible (True)]
public sealed class Obsoleteattribute:attribute {
public ObsoleteAttribute ();
Public ObsoleteAttribute (String message);
Public ObsoleteAttribute (String message, bool error);
public bool IsError {get;}
public string Message {get;}
}
}
Add the format of an attribute (positional and named parameters)
First, we should be able to find that he inherits from attribute, which means that our recordattribute should also inherit from the attribute class. (The difference between an attribute class and a normal class is that it inherits the attribute Class)
Secondly, we find that in the definition of this feature, three features are used to describe him. These three features are: Serializable,attributeusage and ComVisible. Serializable and ComVisible characteristics is relatively simple, is a sign, attributeusage more important, there are three important parameters can be set, said above.
Here we should note that the attribute itself is the metadata used to describe the data, and these three attributes are used to describe the attributes, so they are "meta data" (meta data).
From here we can see that the attribute class itself can also be described in addition to its own characteristics, so the characteristics of the attribute class of the meta-data.
Faint we need to use meta data there is no description of the feature Recordattribute we define, so now we need to look at "meta data". Here you should remember that "meta data" is also a feature, in most cases, We just have to master the AttributeUsage. Now let's delve into it. Let's take a look at how the above AttributeUsage is loaded onto the ObsoleteAttribute feature.
[AttributeUsage (6140,inheritedfalse)]
Look at the definition of AttributeUsage:
Namespace System {
public sealed class Attributeusageattribute:attribute {
Public AttributeUsageAttribute (AttributeTargets Validon);
public bool AllowMultiple {get; set;}
public bool inherited {get; set;}
Public AttributeTargets Validon {get;}
}
}
As you can see, the first constructor, which contains a positional parameter of type AttributeTargets (positional Parameter) Validon, also has two named parameters (Named Parameter). Note the Validon property is not a named parameter because he does not contain a set accessor, which is a positional parameter.
There may be doubts here, why this partition of parameters, which is related to the use of features, adding AttributeUsageAttribute is an ordinary class, we will certainly use:
Instantiate the AttributeUsageAttribute class
AttributeUsageAttribute usage=new AttributeUsageAttribute (attributetargets.class);
Usage. allowmultiple=true;//Setting the AllowMultiple property
Usage. inherited=false;//Setting the Inherited property
However, the attribute is written in a single line of code, and then close to the type (target type) to which it is applied. Daniel thought: Whether it is a constructor parameter or a property, Tong Tong writes to the parentheses of the constructor, for the parameters of the constructor, it must follow the order and type of the constructor parameters, and for the property, take the attribute = value "In such a format, they are separated by commas. The above code is reduced to the following:
[AttributeUsage (Attributetargets.class,allowmutliple=true,inherited=false)]
As you can see, AttributeTargets.Class is the parameter of the constructor (positional arguments), and allowmutliple and inherited are actually attributes (named arguments). Named parameters are optional. Our recordattribute will be used in the same way in the future. (Why these properties are called count, probably because they are used in a way that looks more like the parameters of the method)
Assuming that our recordattribute is ok now, it should be used like this:
[Recordattribute ("Create", "Syx", "2015-8-8", memo= "Hello,world")]
public class DemoClass
{
DoSomething
}
where Recordtype,author and date are positional parameters, Memo is a named parameter
C # Custom attributes: Attributetarget bit markers
You can see from the name of the AttributeUsage attribute that it is used to describe how the attribute is used. Specifically, The first should be which types or objects the attributes it marks can be applied to. From the code above, you can see that the constructor for the AttributeUsage attribute accepts a parameter of type AttributeTargets, So let's get to know AttributeTargets now.
AttributeTargets is a bit tag that defines the types and objects that an attribute can apply to.
[Flags]
public enum AttributeTargets {
Assembly = 1,//You can apply properties to an assembly.
module = 2,//You can apply properties to the module.
class = 4,//You can apply properties to the class.
struct = 8,//You can apply a property to the structure, that is, the value type.
enum = 16,//You can apply a property to an enumeration.
Constructor = 32,//The property can be applied to the constructor.
METHOD = 64,//The property can be applied to the methods.
property = 128,//attribute (Attribute) can be applied to the property.
field = 256,//You can apply a property to a field.
event = 512,//The attribute can be applied to events.
Interface = 1024,//properties can be applied to the interface.
Parameter = 2048,//The attribute can be applied to the parameter.
Delegate = 4096,//The attribute can be applied to the delegate.
returnvalue = 8192,//The property can be applied to the return value.
Genericparameter = 16384,//You can apply properties to generic parameters.
all = 32767,//You can apply attributes to any application element.
}
The above examples are used:
[AttributeUsage (Attributetargets.class,allowmutiple=true,inherited=false)]
The AttributeUsage loaded in the ObsoleteAttribute feature is this:
[AttributeUsage (6140,inherited=false)]
Because AttributeUsage is a tag, you can use a bitwise or ' | ' To make a combination. So, when we write this:
[AttributeUsage (attributetargets.class| Attributetargets.interface)
means that you can apply an attribute to a class or to an interface.
Note: Here are the two exceptions, observing the definition of AttributeUsage above, stating that the attributes can also be loaded onto the assembly assembly and module modules, and that these two are our compilation results, and there is no such type in the program, how do we load it? You can use this syntax: [assembly:someattribute (parameter list)], and this statement must precede the beginning of the program statement.
C # Custom Features: Implementing Recordattribute
Now it should be easy to implement Recordattribute, there is no need to make any changes to the theme of the class, we just need to let this class inherit from the attribute class, and mark it with the AttributeUsage attribute ( Suppose we want to apply this attribute to classes and methods):
[AttributeUsage (attributetargets.class| Attributetargets.method,allowmultiple=true,inherited=false)]
public class Recordattribute:attribute
{
Subject
}
Full code:
Using System;
Using System.Collections.Generic;
Using System.Linq;
Using System.Text;
Using System.Threading.Tasks;
Namespace Custom Features
{
Class Program
{
static void Main (string[] args)
{
DemoClass demo = new DemoClass ();
Console.WriteLine (Demo. ToString ());
Console.readkey ();
}
}
[AttributeUsage (AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, inherited = False)]
public class Recordattribute:attribute
{
Private string recordtype;//record type: Update or create
private string author;//author
Private DateTime data;//Date
private string memo;//remarks
The parameters of the constructor are also called positional parameters in the attribute.
Public Recordattribute (String recordtype, string author, string date)
{
This.recordtype = RecordType;
This.author = author;
This.data = convert.todatetime (date);
}
For positional parameters, usually only get access is provided
public string RecordType {get {return recordtype;}}
public string Author {get {return Author;}}
Public DateTime Date {get {return Date;}}
Build an attribute, also called a named parameter in the attribute
public string Memo
{
get {return memo;}
set {memo = value;}
}
}
[Record ("Update", "Wangwu", "2008-1-20", Memo = "Modify ToString () method")]
[Record ("Update", "Lisi", "2008-1-18")]
[Record ("Create", "Zhangsan", "2008-1-15")]
public class DemoClass
{
public override string ToString ()
{
return "hello,world!";
}
}
}
This program may simply output "Hello,world". Our properties also seem to have no effect on the program using "//", in fact, the data we added has been added as metadata to the assembly.
At this point, the use of a complete custom feature has been completed, for example, to help you understand the characteristics of an analogy: you have not seen the face of the netizen dating, about a good time and place, how to solve the problem of not know ta? You can make an appointment and get something special on your hands. This particular thing that is used to identify a person you do not know is equivalent to attribute. So attribute is used for dynamic invocation at run time.
If it is only the content described earlier, or is not enough to explain the practical value of attribute, then from the following chapters we will introduce a few attribute different usages, I believe you will have a new understanding of attribute.
C # programming (71)----------Custom Attributes