[Switch] 1. What are features and features?
[Switch] 1. What are the features?
Preface
When we first started C #, we saw a highlighted keyword in a pair of brackets in the class. I don't know what it is. I don't know what it is. The Tangle is terrible. In fact, it is a feature. For example:
This is the theme we will analyze today.
What are the features?
In my personal understanding, the feature is to modify the modifier of object metadata.
So what is "metadata "?
Metadata is the data used to describe data. (Pretty easy)
For example:
1. is Feature 2. is access modifier 3. declare modifier 4. data Type 5. variable name 6. variable data values, where 1, 2, 3, 4, and 5 are metadata used to describe the data of data (6.
What are the features?
Above Will Obsolete be a modifier similar to public static? Let's look at the decompiled intermediate language.
Unexpectedly, we saw 2, 3, 4, and 5 above, and how 1 (feature) went inside, and it was a kind of incomprehensible stuff, we know that it is not a similar modifier.
Then we move the cursor to the Obsolete in vs and press F12, for example:
It turns out to be a class that inherits the Attrbute class ). What we cannot understand above should be the instantiation of the ObsoleteAttribute class.
Let's answer the above question: what is the feature? The feature is just a class.
Let's customize a feature to play
We can see that the above system features, such as Serializable, AttributeUsage, and Camvisible, are also available in the Obsolete. This feature is called metadata (metadata ).
1. Let's explain the above three features respectively.
Serializable: indicates that the type supports serialization.
ComVisible: Microsoft defines "Access to COM for individual managed types, members, or all types in a control set ".
AttributeUsage: This is very important. It is basically used for each feature definition. It is used to indicate which objects this feature can be used. Such as: Class, method, attribute... and so on. (You only need to use this to customize features)
2. There is a problem above. I don't know if you find it.
That is, our feature name is Obsolete. Why does F12 become ObsoleteAttribute after it is entered? This is actually just a Microsoft agreement.
In fact, we can use two methods: [ObsoleteAttribute ("Obsolete")] and [Obsolete ("Obsolete")] are equivalent, but we generally use this method later.
3. defined features must inherit from Attribute.
4. The property does not have the set method. You can only assign values through constructors. (This is due to the feature syntax, because the feature definition only exists in the brackets of a single row, and cannot be instantiated before setting the attribute. Therefore, all the settings are carried out in the parentheses. If you need the set attribute, we need to use the named parameter. We will continue to discuss it below)
Now, we can define a feature by ourselves through these four points. Let's define a comment for the machine. Our usual comments are only for programmers. After compilation, all the comments are lost. What should we do when we pop up our comments during code execution? Next we will use custom features for implementation, such:
[AttributeUsage (AttributeTargets. All)] // 3. Set which objects can be used for public class TMessgAttribute: Attribute // 1. Define class TMessg plus suffix TMessgAttribute 2. inherit Attribute. {Public TMessgAttribute () {}/// <param name = "createTime"> creation time </param> /// <param name = "createName"> creator </param> public TMessgAttribute (string createTime, string createName, string mess) {this. _ createName = createName; this. _ createTime = createTime; this. _ mess = mess;} private string _ createTime; public string createTime {get {return _ createTime;} // 4. only get method} private string _ createName; public string createName {get {return _ createName;} private string _ mess; public string mess {get {return _ mess ;}}}
Well, the above is our custom feature. So how can we use it. Same as system features. We first define a test class TClass and then define features on the class, such:
[TMessg ("2015-12-20", "zhaopei", "I'm just testing custom features. do not report any errors. I beg you. ")] Public class TClass {//................}
We have defined and used features, but we do not know how to view the results. We want to see what to do. You can use reflection (continue to analyze reflection in the next blog) to view TClass metadata, such:
Static void Main (string [] args) {System. reflection. memberInfo info = typeof (TClass); // obtain the TClass information through reflection TMessgAttribute hobbyAttr = (TMessgAttribute) Attribute. getCustomAttribute (info, typeof (TMessgAttribute); Console. writeLine ("Class Name: {0}", info. name); Console. writeLine ("Creation Time: {0}", hobbyAttr. createTime); Console. writeLine ("created by: {0}", hobbyAttr. createName); Console. writeLine ("Remarks: {0}", hobbyAttr. mess); Console. readKey ();}
The printing result is as follows:
What are named parameters?
The above custom features are all set by the constructor field private field, and then accessed by only providing the get attribute. Can we define the get and set attributes in the feature directly? The answer is yes. So how to set this attribute when using the feature? Let's look down.
We then add an attribute in the Custom feature.
/// <Summary> /// modification time /// </summary> public string modifyTime {get; set ;}
Use custom features.
[TMessg ("2015-12-20", "zhaopei", "I'm just testing custom features. do not report any errors. I beg you. ", ModifyTime =" 2015-12-21 ")] public class TClass {//................}
We found that after the constructor is input, you can set the attribute. (This is equivalent to an optional parameter. You can set the attribute as needed. However, you must note that the preceding parameters must follow the defined parameter order of the constructor)
This parameter is a named parameter.
Let's continue to look at AttributeUsage (the feature of this description feature-"metadata ")
Let's look at the definition of AttributeUsage in F12.
It seems that it is just a common feature. It is actually just a common feature.> _ <
Let's see what these attributes are. Start from the last one.
1. AttributeTargets, which we have already seen and used.
We set the options for all objects. AttributeTargets is actually an enumeration. Each value is for a type object.
You can go directly to AttributeTargets F12:
We can see that each value represents the object type that can be used.
2. Inherited (a Boolean value): "true if this attribute can be Inherited by a derived class and override member; otherwise, false. The default value is true"
As follows, if we set Inherited = false, the T2Class that inherits the TClass cannot access the feature metadata set in the TClass.
Namespace net {[AttributeUsage (AttributeTargets. all, Inherited = false)] // 3. set which objects can be used for public class TMessgAttribute: Attribute // 1. define the class TMessg with the suffix TMessgAttribute 2. inherit Attribute. {Public TMessgAttribute () {}/// <param name = "createTime"> creation time </param> /// <param name = "createName"> creator </param> public TMessgAttribute (string createTime, string createName, string mess) {this. _ createName = createName; this. _ createTime = createTime; this. _ mess = mess;} private string _ createTime; public string createTime {get {return _ createTime;} // 4. only get method} private string _ createName; pu Blic string createName {get {return _ createName;} private string _ mess; public string mess {get {return _ mess ;}} /// <summary> /// modification time /// </summary> public string modifyTime {get; set ;}} class Program {static void Main (string [] args) {System. reflection. memberInfo info = typeof (T2Class); // obtain the information of the TClass class through reflection TMessgAttribute hobbyAttr = (TMessgAttribute) Attribute. getCustomAttribute (inf O, typeof (TMessgAttribute); Console. WriteLine ("Class Name: {0}", info. Name); if (hobbyAttr! = Null) {Console. writeLine ("Creation Time: {0}", hobbyAttr. createTime); Console. writeLine ("created by: {0}", hobbyAttr. createName); Console. writeLine ("Remarks: {0}", hobbyAttr. mess); Console. writeLine ("modification time: {0}", hobbyAttr. modifyTime);} Console. readKey () ;}} [TMessg ("2015-12-20", "zhaopei", "I'm just testing custom features. Don't report an error. Please. ", ModifyTime =" 2015-12-21 ")] public class TClass {//................} public class T2Class: TClass {//...........}}
View Code
Otherwise, we set Inherited = true (or do not set any, because the default value is true) to print as follows:
3. AllowMultiple (also a Boolean value): "true if multiple instances are allowed; otherwise, false. The default value is false ."
Let's try setting two features, such:
What should we do if we want to set it like this. Set AllowMultiple = true in AttributeUsage, for example:
The above error will be printed:
Note: The Code of the printed area above needs to be modified. Because a feature information is printed before, the information of a feature array is printed here.
Static void Main (string [] args) {System. reflection. memberInfo info = typeof (T2Class); TMessgAttribute [] hobbyAttr = (TMessgAttribute []) Attribute. getCustomAttributes (info, typeof (TMessgAttribute); // modify 1. the Console is a collection of feature data. writeLine ("Class Name: {0}", info. name); for (int I = 0; I
All code:
Using System; using System. collections. generic; using System. linq; using System. runtime. interopServices; using System. text; using System. threading. tasks; namespace net {[AttributeUsage (AttributeTargets. all, Inherited = true, AllowMultiple = true)] // 3. set which objects can be used for public class TMessgAttribute: Attribute // 1. define the class TMessg with the suffix TMessgAttribute 2. inherit Attribute. {Public TMessgAttribute () {}/// <param name = "createTime"> creation time </param> /// <param name = "createName"> creator </param> public TMessgAttribute (string createTime, string createName, string mess) {this. _ createName = createName; this. _ createTime = createTime; this. _ mess = mess;} private string _ createTime; public string createTime {get {return _ createTime;} // 4. only get method} private string _ createName; pu Blic string createName {get {return _ createName;} private string _ mess; public string mess {get {return _ mess ;}} /// <summary> /// modification time /// </summary> public string modifyTime {get; set ;}} class Program {static void Main (string [] args) {System. reflection. memberInfo info = typeof (T2Class); TMessgAttribute [] hobbyAttr = (TMessgAttribute []) Attribute. getCustomAttributes (info, typeof (TMes SgAttribute); // modify 1. the Console is a collection of feature data. writeLine ("Class Name: {0}", info. name); for (int I = 0; I What are the custom features of View Code?
Through decompilation, we found that the user-defined feature is actually a piece of instantiated code added at the very beginning of an object call.
So we can do more things. In addition to setting "Comments" for objects like above, we can also customize features, perform "Operation Log Record" for some methods or classes, or grant permissions required when executing some methods. We can implement permission authentication features and so on.
Here we need to expand it by ourselves.
This article has been synchronized to C # basic knowledge consolidation Series