Lecture 7 domain and attributes
Li Jianzhong (cornyfield@263.net), Nanjing University of Posts and Telecommunications)
|
|
|
|
C # Sharp experience |
|
|
|
|
"Hello, world! "Program |
|
|
|
|
C # BASIC Language Introduction |
|
|
|
|
Basic Structure of Microsoft. NET platform |
|
|
|
|
Class and Object |
|
|
|
|
Constructor and destructor |
|
|
|
|
Method |
|
|
|
|
Domain and attribute |
|
|
|
|
Indexer and operator overload |
|
|
|
|
Array and string |
|
|
|
|
Features and ing |
|
|
|
|
Com interoperability with unmanaged programming and Exception Handling |
|
|
|
|
Use C # to weave the future -- C # programming model Overview |
|
|
|
|
|
Domain
Field, also known as member variable, represents the storage location and is an indispensable part of the class in C. The domain type can be any data type in C. However, we will not mention other reference types except the string type because some class constructor operations are involved during initialization, we will introduce this part of content as "nesting of classes" in the "interface inheritance and polymorphism" section.
Domains are divided into instance domains and static domains. The instance domain is a specific object and is private to a specific object. Static fields belong to the class and are shared by all objects. C # Strictly stipulate that instance domains can only be obtained through objects, and static domains can only be obtained through classes. For example, if we have an object of the myclass type myobject, The instancefield of the Instance domain in myclass (the access restriction is public) can only be obtained as follows: myobject. instancefield. The static field staticfield of myclass (the access restriction is public) can only be obtained as follows: myclass. staticfield. Note that static fields cannot be obtained through objects as traditional C ++ does. That is to say, the usage of myobject. staticfield is incorrect and cannot be compiled by the compiler.
Domain access restrictions reflect the encapsulation principles of object-oriented programming. As mentioned above, there are 5 types of access restriction modifiers in C #, which are applicable to the domain. C # extends the original friend modifier of C ++ with internal. When it is necessary to make some fields of the two classes visible to each other, we declare the fields of these classes as internal, and then compile them in a composite body. If you need to be visible to their inherited child classes, declare them as protected internal. In fact, this is also the original meaning of the combination-encapsulate the logical-related classes together.
C # introduces the readonly modifier to represent the read-only domain, and const to represent constant. As the name implies, the read-only domain cannot be written, and constant cannot be modified. What is the difference between the two? A read-only domain can only be assigned a value during initialization -- declaring initialization or constructor initialization -- and cannot be assigned to a read-only domain elsewhere. Otherwise, the compiler reports an error. The read-only domain can be an instance domain or a static domain. The type of the read-only domain can be any type of the C # language. However, the const-modified constant must be assigned a value at the same time as it is declared, and the compiler is required to calculate this definite value during compilation. The constant modified by const is a static variable and cannot be obtained by the object. The type of the value modified by const is also limited. It can only be one of the following types (or can be converted to the following types): sbyte, byte, short, ushort, Int, uint, long, ulong, Char, float, double, decimal, bool, String, Enum type, or reference type. It is worth noting that the reference type here, except for the string type, all types out of the null value cannot be calculated by the compiler during the compilation period, therefore, the reference type declared as const can only be string or other reference types whose values are null. Obviously, when we declare a null constant, we have lost the meaning of the Declaration-this can be said to be the embarrassment of C # design!
That is to say, when we need a const constant, but its type limits it to be unable to calculate a definite value during compilation, we can solve this problem by interpreting the voice as static readonly. However, there is a slight difference between the two. See the following two different files:
// File1.cs // CSC/T: Library file1.csusing system; namespace mynamespace1 {public class myclass1 {public static readonly int myfield = 10 ;}// file2.cs // CSC/R: file1.dll file2.csusing system; namespace mynamespace2 {public class myclass1 {public static void main () {console. writeline (mynamespace1.myclass1. myfield );}}}
Our two classes belong to two files, file1.cs and file2.cs, and are compiled separately. When the field myfield in the file file1.cs is declared as static bytes, we will get 20. However, if we change static readonly to const and then change the initialization value of myfield, we must re-compile all files referenced in file1.dll; otherwise, we will reference mynamespace1.myclass1. myfield will not change as we wish. This requires special attention in the Process of Large system development. In fact, if we can understand that the constant modified by const is calculated at the time of compilation and replaced by every place that references the constant, the readonly value is determined at runtime. It is only after initialization that we don't want its value to change. We can understand the painstaking efforts of C # designers, we can thoroughly grasp the const and readonly actions!
Domain Initialization is a special issue in object-oriented programming. C # The Compiler initializes each domain as its default value by default. In short, the default value of the value type (Enumeration type) is 0 or 0.0. The default value of the character type is '\ x0000 '. The default value of boolean type is false. The default value of the reference type is null. The default value of the structure type is the corresponding default value for all its types. Although the C # compiler sets the default type for each type, as an object-oriented design principle, we still need to initialize the variables correctly. In fact, this is also the recommended practice of C #. If the domain is not initialized, the compiler will issue a warning message. C # There are two places to initialize the domain: Initialize the declaration at the same time and initialize the domain in the constructor. As mentioned above, the Declaration initialization of the domain is actually executed by the compiler as a value assignment statement at the beginning of the constructor. Instance variable initialization will be placed in the instance constructor, and static variable initialization will be placed in the static constructor. If we declare a static variable and initialize it at the same time, the compiler will construct a static constructor for us to put this initialization statement into a value assignment statement. As a constant volume field modified by const, it cannot be regarded as an initialization statement strictly. we can regard it as a macro replacement similar to C ++.
Attribute
Attribute can be said to be an innovation of C # language. Of course, you can say no. The reason is that the implementation behind it is actually two functions-one value assignment function (get) and one value function (SET), which is generated from the intermediate languageCodeYou can see it clearly. The reason is that it does realize the special interface of object-oriented programming for the OO Style Class "attribute" at the language level. The original intention of understanding attributes is to make good use of attributes. C # It is not recommended to set the protection level of the domain to public so that users can perform any operation outside the class-that is too non-oo, or the specific point is too insecure! For all fields that need to be visible outside the class, C # is recommended to use attributes for representation. The attribute does not represent the storage location, which is the fundamental difference between the attribute and the domain. The following is a typical attribute design:
Using system; Class myclass {int integer; Public int INTEGER {get {return integer;} set {INTEGER = value ;}} class test {public static void main () {myclass myobject = new myclass (); console. write (myobject. integer); myobject. integer ++; console. write (myobject. integer );}}
As we expected, the program outputs 0 1. We can see that attributes provide a friendly access interface for domain members to programmers through method packaging. Here, value is the key word of C #, which is the implicit parameter of set when we perform attribute operations, that is, the right value when we perform attribute write operations.
Attribute provides read-only (get), write-only (SET), read-write (get and set) Three interface operations. The three operations on the domain must be declared under the same attribute, but they cannot be separated. See the following implementation:
Class myclass {private string name; Public string name {get {return name ;}} public string name {set {name = value ;}}}
The preceding method for separating the name attribute is incorrect! We should put them together like in the previous example. It is worth noting that the three attributes (read-only, write-only, read-write) are considered by C # As the same attribute name. See the following example:
Class myclass {protected int num = 0; Public int num {set {num = value ;}} class myclassderived: myclass {New Public int num {get {return num ;}}} class test {public static void main () {myclassderived myobject = new myclassderived (); // myobject. num = 1; // error! (Myclass) myobject). num = 1 ;}}
We can see that the property num-get {} In myclassderived shields the definition of the property num-set {} In myclass.
Of course, the attribute is far more than just the interface operation of the domain. The nature of the attribute is still the method. We can perform some checks, warnings, and other additional operations according to the program logic during Attribute Extraction or assignment, see the following example:
Class myclass {private string name; Public string name {get {return name;} set {If (value = NULL) name = "Microsoft"; elsename = value ;}}}
Because of the nature of the attribute method, attributes also have various methods for modification. There are also five types of access modifiers for attributes, but the access modifier for attributes is usually public. Otherwise, we will lose the meaning of attributes as the public interface of the class. In addition to the non-existent feature attributes such as method overloading caused by multiple parameters of methods, virtual, sealed, override, and abstract modifiers perform the same behavior on attributes and methods, however, because attributes are implemented as two methods in essence, we need to pay attention to some of its behaviors. See the following example:
Abstract class A {int y; Public Virtual int X {get {return 0 ;}} Public Virtual int y {get {return y ;}set {Y = value ;}} public abstract int Z {Get; Set ;}} Class B: A {int Z; Public override int X {get {return base. X + 1 ;}} public override int y {set {base. y = value <0? 0: Value ;}} public override int Z {get {return Z;} set {z = value ;}}}
This example focuses on some typical behaviors of attributes in the inheritance context. Here, Class A must be declared as abstract because of the existence of abstract attribute Z. In subclass B, the attribute of parent class A is referenced by the base keyword. In Class B, the virtual attribute in Class A can be overwritten only through Y-set.
Static attributes, like static methods, can only access static domain variables of the class. We can also declare external attributes like external methods.