To differentiate the two properties (Property and Attribute) in C)

Source: Internet
Author: User
Difference C # two properties (Property and Attribute) in C # Have two properties in C #: Property and Attribute, respectively, both Chinese meanings include features and attributes, but their usage is different. For the sake of difference, this article calls Property a feature and Attribute a Property. Property is relatively simple, that is, get and set, which are commonly used to provide interfaces for reading and setting the private and protected variables in the class. About Property please refer to my article: http://blog.csdn.net/tjvictor/archive/2006/06/23/824617.aspx Attribute is the main character of this article, it is called Attribute I think very appropriate. Attribute refers to a description of the characteristics of a thing attached to a thing. Attribute does this. It allows you to associate information with the C # type you define as a Type annotation. This information is arbitrary, that is, it is not determined by the language itself. You can establish and associate any type of information at will. You can define the design information and runtime information, or even the behavior characteristics of the runtime. The key lies in that the information can be extracted by the user as a type of annotation, which can be recognized by the compiler and used as a subsidiary condition for compilation. The following content and code are derived from the definition attributes of Inside C # Sencond Edition: an Attribute is actually a class derived from the System. Attribute base class. The System. Attribute Class contains several methods for accessing and checking custom attributes. Although you have the right to define any class as an Attribute, it makes sense to use the System. Attribute derived class by convention. Example: public enum RegHives {region, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_CONFIG} public class RegKeyAttribute: Attribute {public RegKeyAttribute (RegHives Hive, String ValueName) {this. hive = Hive; this. valueName = ValueName;} protected RegHives hive; public RegHives Hive {get {return hive;} set {hive = value ;}} protected String valueName; public Str Ing ValueName {get {return valueName;} set {valueName = value ;}} here we have added enumeration of different registries, attribute class constructors, and two properties ). You can do a lot of things when defining attributes. Let's look at how to query attributes at runtime. To query the type or attributes attached to a member at run time, you must use reflection. See my other simple article on reflection http://blog.csdn.net/tjvictor/archive/2007/01/24/1492079.aspx query class attributes: Suppose you want to define an attribute, this attribute defines the remote server on which the object will be created. Without this attribute, you need to save this information in a constant or resource file of an application. To use attributes, you only need to use the following method to mark the remote server name of the class: using System; namespace QueryAttribs {public enum RemoteServers {JEANVALJEAN, JAVERT, COSETTE} public class RemoteObjectAttribute: attribute {public RemoteObjectAttribute (RemoteServers Server) {this. server = Server;} protected RemoteServers server; public string Server {get {return RemoteServers. getName (typeof (RemoteServers), this. server) ;}} [RemoteObject (Re MoteServers. COSETTE)] class MyRemotableClass {} class Test {[STAThread] static void Main (string [] args) {Type type = typeof (MyRemotableClass); foreach (Attribute attr in type. getCustomAttributes (true) {RemoteObjectAttribute remoteAttr = attr as RemoteObjectAttribute; if (null! = RemoteAttr) {Console. writeLine ("Create this object on {0 }. ", remoteAttr. server) ;}} Console. readLine () ;}}: Creat this object on COSETTE. Note: In this example, the Attribute class name has an Attribute suffix. However, when we attach this Attribute to a type or member, the Attribute suffix is not included. This is a simple method provided by the C # Language designer. When the compiler sees an Attribute attached to a type or member, it searches for a System. Attribute derived class with the specified Attribute name. If the compiler does not find a matching class, it adds Attribute after the specified Attribute name and then searches for it. Therefore, it is common to define an Attribute class name as ending with an Attribute and ignore this part of the name during use. The following code uses this naming method. Query Method attributes: In the following example, we define a method as a transactional method using attributes. As long as the TransactionableAttribute exists, the code knows that the method with this attribute can belong to a transaction. Using System; using System. reflection; namespace MethodAttribs {public class TransactionableAttribute: Attribute {public TransactionableAttribute () {}} class SomeClass {[Transactionable] public void Foo () {} public void Bar () {} [Transactionable] public void Goo () {}} class Test {[STAThread] static void Main (string [] args) {Type type = Type. getType ("MethodAttribs. someClass "); foreach (Method Info method in type. getMethods () {foreach (Attribute attr in method. getCustomAttributes (true) {if (attr is TransactionableAttribute) {Console. writeLine ("{0} is transactionable. ", method. name) ;}} Console. readLine () ;}}: Foo is transactionable. goo is transactionable. query field attributes: Assume that a class contains some fields, and we want to save their values to the Registry. To this end, you can use the constructor with enumerated values and strings as parameters to define an attribute. This enumerated value represents the correct registry hive, and the string represents the registry value name. You can query the registry key of a field at runtime. Using System; using System. reflection; namespace FieldAttribs {public enum RegHives {region, region, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CURRENT_CONFIG} public class RegKeyAttribute: Attribute {public RegKeyAttribute (RegHives Hive, String ValueName) {this. hive = Hive; this. valueName = ValueName;} protected RegHives hive; public RegHives Hive {get {return hive;} set {Hive = value ;}} protected String valueName; public String ValueName {get {return valueName;} set {valueName = value ;}} class SomeClass {[RegKey (RegHives. HKEY_CURRENT_USER, "Foo")] public int Foo; public int Bar;} class Test {[STAThread] static void Main (string [] args) {Type type = Type. getType ("FieldAttribs. someClass "); foreach (FieldInfo field in type. getFields () {foreach (Attribu Te attr in field. GetCustomAttributes (true) {RegKeyAttribute rka = attr as RegKeyAttribute; if (null! = Rka) {Console. writeLine ("{0} will be saved in" + "{1 }\\\{ 2}", field. name, rka. hive, rka. valueName) ;}} Console. readLine () ;}} the running result is: Foo will be saved in HKEY_CURRENT_USER \ Foo. You can see that attributes are used to mark classes, methods, and fields, the user-defined information can be attached to an entity and can be dynamically queried at runtime. Below I will talk about some default predefined attributes in C #, as shown in the following table:
Predefined attributes Effective Target Description
AttributeUsage Class Specify the valid usage of another attribute class
CLSCompliant All Indicates whether the program element is compatible with CLS.
Conditional Method Indicates that if no associated string is defined, the compiler can ignore any call to this method.
DllImport Method Specifies the DLL location that contains the implementation of external Methods
STAThread Method (Main) Indicates that the default thread model of the program is STA.
MTAThread Method (Main) Specifies that the default program model is multi-thread (MTA)
Obsolete Besides Assembly, Module, Parameter, and Return Mark an element as unavailable, notifying users that this element will be used by future products
ParamArray Parameter Allows a single parameter to be treated implicitly as a params (array) parameter
Serializable Class, Struct, enum, delegate All public and private fields of this type can be serialized.
NonSerialized Field Applies to Fields marked as serializable classes, indicating that these fields cannot be serialized
StructLayout Class, struct Specifies the nature of the data layout of a class or structure, such as Auto, Explicit, or sequential
ThreadStatic Field (static) Implement local thread storage (TLS ). A given static field cannot be shared across multiple threads. Each thread has a copy of this static field.
The following describes several common attributes. [STAThread] and [MTAThread] Attribute class Class1 {[STAThread] Static void Main (string [] args) {}} use the STAThread attribute to specify the default thread model of the program as a single-thread model. Note that the thread model only affects applications that use COM interop. Applying this attribute to programs that do not use COM interop will not produce any effect. 2. The AttributeUsage attribute can be used to label custom attributes of the General C # type. You can also use the AttributeUsage attribute to define how you use these attributes. The AttributeUsage attribute of a file record is called as follows: public enum AttributeTargets {Assembly = 0x0001, Module = 0x0002, Class = 0x0004, Struct = 0x0008, Enum = 0x0010, Constructor = 0x0020, method = 0x0040, Property = 0x0080, Field = 0x0100, Event = 0x200, Interface = 0x400, Parameter = 0x800, Delegate = 0x1000, All = Assembly | Module | Class | Struct | Enum | Constructor | Method | Property | Filed | Event | Interface | Parameter | Deleagte, classMembers = | Class | Struct | Enum | Constructor | Method | Property | Field | Event | Delegate | Interface} AllowMultiple determines how many times a certain attribute can be used on a single Field, by default, all attributes are used at a time. Example: [AttributeUsage (AttributeTargets. all, AllowMultiple = true)] public class SomethingAttribute: Attribute {public SomethingAttribute (string str) {}} // If AllowMultiple = false, [Something ("abc")] [Something ("def")] the class Myclass {} Inherited parameter indicates whether the property can be Inherited. The default value is false.
Inherited AllowMultiple Result
True False The derived attribute overwrites the base attribute.
True False The derived attributes and the base attributes coexist.
Sample Code: using System; using System. reflection; namespace AttribInheritance {[AttributeUsage (AttributeTargets. all, AllowMultiple = true, // AllowMultiple = false, Inherited = true)] public class SomethingAttribute: Attribute {private string name; public string Name {get {return name ;} set {name = value ;}} public SomethingAttribute (string str) {this. name = str ;}} [Something ("abc")] class MyClass {} [Something ("def")] class Another: MyClass {} class Test {[STAThread] static void Main (string [] args) {Type type Type = Type. getType ("AttribInheritance. another "); foreach (Attribute attr in type. getCustomAttributes (true) // type. getCustomAttributes (false) {SomethingAttribute sa = attr as SomethingAttribute; if (null! = Sa) {Console. writeLine ("Custom Attribute: {0}", sa. name) ;}}}}when AllowMultiple is set to false, the result is: Custom Attribute: def. When AllowMultiple is set to true, the result is: Custom Attribute: defCustom Attribute: abc Note: if false is passed to GetCustomAttributes, it will not search for the inheritance tree, so you can only get the derived class attributes. 3. You can attach the Conditional attribute to the method. In this way, when the compiler calls this method, if the corresponding string value is not defined, the compiler ignores this call. For example, whether the following method is compiled depends on whether the string "DEGUG" is defined: [Condition ("DEBUG")] public void SomeDebugFunc () {Console. writeLine ("SomeDebugFunc");} using System; using System. diagnostics; namespace CondAttrib {class Thing {private string name; public Thing (string name) {this. name = name; # if DEBUG SomeDebugFunc (); # else SomeFunc (); # endif} public void SomeFunc () {Console. writeLine ("SomeFunc");} [Conditional ("DEBUG")] [Condit Ional ("ANDREW")] public void SomeDebugFunc () {Console. writeLine ("SomeDebugFunc") ;}} public class Class1 {[STAThread] static void Main (string [] args) {Thing t = new Thing ("T1 ");}}} 4. with the continuous development of the code, you may not need to use some methods. You can delete them all, but sometimes adding appropriate labels to them is more appropriate than deleting them, for example: using System; namespace ObsAttrib {class SomeClass {[Obsolete ("Don't use OldFunc, use NewFunc instead", true)] public void OldFunc () {Console. writeLine ("Oops");} public void NewFunc () {Console. writeLine ("Cool") ;}} class Class1 {[STAThread] static void Main (string [] args) {SomeClass SC = new SomeClass (); SC. newFunc (); // SC. oldFunc (); // compiler error }}} We set the second parameter of the Obsolete attribute to true. The compiler will generate an error when calling the function. E: \ InsideC # \ Code \ Chap06 \ ObsAttrib \ Class1.cs (20): 'obsattrib. someClass. oldFunc () 'expired: 'don' t use OldFunc, use NewFunc instead' 5. the DllImport and StructLayout attributes of DllImport allow C # code to call functions in the local code. C # code calls them through the runtime function of platform invoke. If you want the runtime environment to correctly organize the structure from the managed code into unmanaged code (or vice versa), you need to add attributes to the schema declaration. In order for structure parameters to be correctly grouped, The StructLayout attribute must be used to declare them, indicating that the data should be arranged strictly according to the format listed in the Declaration. If this is not done, data cannot be correctly grouped, and applications may encounter errors. Using System; using System. runtime. interopServices; // for DllImport namespace nativeDLL {public class Test {// [DllImport ("user32.dll")] // all the defaults are OK [DllImport ("user32 ", entryPoint = "MessageBoxA", SetLastError = true, CharSet = CharSet. ansi, ExactSpelling = true, CallingConvention = CallingConvention. stdCall)] public static extern int MessageBoxA (int h, string m, string c, int type); [Stru CtLayout (LayoutKind. sequential)] public class SystemTime {public ushort wYear; public ushort wMonth; public ushort hour; public ushort wDay; public ushort wHour; public ushort wMinute; public ushort wSecond; public ushort hour ;} [DllImport ("kernel32.dll")] public static extern void GetLocalTime (SystemTime st); [STAThread] public static void Main (string [] args) {MessageBoxA (0, "H Ello World "," nativeDLL ", 0); SystemTime st = new SystemTime (); GetLocalTime (st); string s = String. format ("date: {0}-{1}-{2}", st. wMonth, st. wDay, st. wYear); string t = String. format ("time: {0 }:{ 1 }:{ 2}", st. wHour, st. wMinute, st. wSecond); string u = s + "," + t; MessageBoxA (0, u, "Now", 0) ;}} 6. when using accessory attributes. NET will automatically generate an AssemblyInfo. cs source code file and application source code file. AssemblyInfo. cs contains the code in the accessory. Some of the information is purely information, while other information enables the runtime environment to ensure the unique name and version number for the Customer Code to reuse your accessories. 7. The context property. NET Cabinet also provides another property: context property. Context properties provide an intercept mechanism that can be processed before and after class instantiation and method calling. This function is used for remote object calls. It is used from the COM + component Services and Microsoft Transaction Services (MTS) used by the COM-based system ).

 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx? PostId = 1492913

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.