[preface]
Although Microsoft Visual Studio .NET 2005 (in the past is called Visual Studio .NET 2004) repeatedly postponed its release date, the majority of developers have also appear to have a network. But the article related to the C # seems to have no more than two aspects: VS.NET 2005 IDE features, introduce the "four major features (generics, anonymous methods, iterators, and incomplete types) introduced in C # 2.0. I don't want to talk about the study of IDE, Microsoft is Microsoft, and his window app has not said. For the improvement of language itself, after I have finished Anders Hejlsberg in Microsoft Professional Developers Conference 2003 (2003.10, Los Angeles, CA), there were some freshly known Features, even in Microsoft's official document "C # Language Specification Version 2.0" is not mentioned. These characteristics have more improved language logic. So I wrote a large number of actual programs to study these features and finally the book. This intent is published in the "9CBS Development Master" magazine, but it can be limited to this corner. It can only be rare in this corner. I hope to be able to help those friends who have a strong interest in C # languages.
--Lover_P 221 bedroom in Building 1, Beijing University of Technology
[Revision instructions]
2004-08-24 The first revision. Modified a large number of typical words and grammar errors. Added an introduction to the Global qualifier.
[text]
Microsoft adds many new features that make up the programmers in its upcoming C # 2.0 (Visual C # Whidbey). In addition to major improvements such as generic, iterators, anonymynous and incomplete type (Partial Type), it also has great improvements to existing syntax details, which is very convenient. The NET framework is designed and further enhances the unique high logic of C # language. In this article, I will introduce these improvements to you. (C # refer to the C # 1.2 and previous version, while C # 2.0 refers to Microsoft's C # whidbey in Microsoft, and all the code in the article is on the C # compiler of 8.00.30703.4. Test, the error message marked with * is from the C # compiler of version 7.10.3052.4.)
[content]
Accessibility of static class properties Limit namespace alias
Global Limited Compiler Directive Fixed Size Buffer Reference
Static class
People who use C # to do .NET framework programming should know that a class declare is static. For example, the following category:
Public static class a {static int}
In C # is invalid, when we try to compile this code, you will get the following compilation error *:
Error CS0106: The modifier "static" is invalid
Since it is unable to modify a class with Static modifiers, we always declare that static members have declared instance members in the class. This will undoubtedly bring great flexibility. However, if we want a class to be static, it is to force all members in this class should be static, and it is not powerful, the only thing to do is to pay attention to the statement of all members as static. When we forget to use Static modifiers for a static member (although this is a "low-level error", it is still possible to happen, it will produce an unpredictable error. Most importantly, for a logical static class (all members use the Static modifier declared class), we can even declare a variable of such a class and use the new operator to generate instances of this class! This is obviously not what we expect. In C # 2.0, a static class is provided, allowing Static modifiers to modify classes, and the above code is compiled. If a STATIC modifier is included in a class declaration, all members in this class will be mandatory to declare static. At this time, if we deliberately declare an instance member or accidentally forget the Static modifier in the member statement, as shown in the following code:
Public static class a {int I;}
The compiler will report an error:
Error CS0708: 'a.i': Cannot Declare Instance Members in A Static Class
At the same time, if we declare the variables of the class or try to establish an instance of this class, as follows:
Public class test {a a a; // error cs0723 void foo () = new a (); // error CS0712}}
The following two compile errors are obtained:
Error CS0723: Cannot Declare Variable of Static Type 'a'error CS0712: Cannot Create An Instance of The Static Class' A'
Obviously, C # 2.0 supports the static class's support to avoid accidents in writing programs, especially the logic of static classes, and improves code readability.
Accessibility of attributes
C # provides us with a fairly convenient attribute definition, allowing us to access the properties of the class like the public variable members of the class, but can also get security like access functions. However, the C # only allows the setting operation of the attribute (set {...}) and the acquisition action (GET {...}) with the same accessibility (specified by a modification of the PUBLIC, INTERNAL, and PRIVATE in the property declaration) . Then, when we want to allow classes from any assembly to get a specific class attribute, but only the assembly of this class or the private member of the class can only set this property as public And read only read (ie, using the public modifier but only get {} domain), and internal or private members can complete the settings of the attribute by setting the value of the internal or private variable member associated with the property:
Public class a {int _intValue; // The member variable / / public and read-only attribute associated with the property, allows any class to get the value of this property: public int value {get {return_intvalue;}} // The following method needs to set the above properties, // but can only be done by accessing the private member variable, / / and to perform an error handling private void someMethod () {INT i; // ...... // below The IF-ELSE statement is only used to set the attribute value: if (0
Private void AnotherMethod () {INT i; // ... // The following IF-ELSE statement is only used to set the attribute value, / / but its error IF is detected to i (0
The above method is incorrect on the check section of the value that will assign a private variable member. This error is very likely to occur. Once this method is called, _intValue is likely to have a value of the error, and the external assembly that accesses the Value property will appear logic errors. This error solve is quite difficult. Also, if other members in a group are responsible for designing other classes in the same program, they are required to write such a large number of code in the method and to perform errors.
Of course, we may think that the work of this setting attribute value is concentrated in an internal method:
{I _ i i (i) {ixTintValue (INTVALUE & S) {IF (0 Although this avoids the appearance of logic errors (at least resolution work when the error occurs), its readability is still not ideal, especially the logic is very poor, and the meaning of "attribute" itself is far away. . However, C # 2.0 allows us to set accessibility to the attribute GET {} and set {} domain, we can simply writing the above code: Public class a {int _intValue; // The member variable // public attribute associated with the property, // allows any class to get the value of this property, // but only the categories inside the assembly and the class Private member // can set the value of the property public int value {get {return _intValue;} interNal set {ix (0 // This is another class in the same program: public class b {public a a a = new a (); a.Value = 8; // This is set to attributes, convenient! Return A;}} It can be seen that the accessibility limits can be set to the attribute acquisibility limit to greatly enhance the readability and language logic of the C # program, and the program written is also more maintenanceability. Namespace alias In C #, you need to specify a fully name of the class using classes (such as declared member variables or call static methods, etc.), namely the name of the namespace prefix. If we want to print "Hello, World!" On the console, you need to write: System.console.writeline ("Hello, World!"); Among them, system is a namespace. Console is the name of the class. WriteLine () is the method we want to call. Such requirements clearly make the code abnormally redundant redundancy. Therefore, C # provides us with the useming key (instruction). By using the USING instruction, we can specify a series of namespaces to the compiler. When the class name appears in the program, the compiler will automatically find this class in these namespaces. Therefore, the above code can be written: Using system; // ...... public class test {public static void main () {console.writeline ("Hello, World!");}} Oh, isn't this a classic "Hello World" example? Obviously, this way of writing is much easier and can greatly improve the development efficiency. However, two namespaces are likely to have the same name, and we just need to use these same names. This situation often occurs. For example, there are three Timer classes in the .NET Framework class: system.timer.timer, system.threading.tims.timer. We are likely to need two Timer classes: a system.timer.timer is used to check the application or system status at a fixed interval in a fixed time interval, a system.windows.forms.timer is used to display simple animation in the user interface. At this time, although we use the using directive, we still need to add namespaces when these classes appear: use system.timer; useing system.windows.forms; // ... public class mainform: form {system .Timer.timer checktimer; system.windows.forms.timer animatetimer; // ......} Such a program still appears to be lengthy. In C # 2.0, the use of the use of the using command is expanded, we can use the USING instruction to specify an alias for the namespace. When we need to quote this namespace, you can simply use its alias. When creating an alias for namespace, we use the use of the extension of the use of instructions: use alias = namespace to specify an alias Alias for named space Namespace. The method of using alias and namespace is identical. When we reference the type in a namespace, you only need to add a dot after the namespace. "He follow the type name; when references the type of namespace represented by an alias, it is the same. of. Then, the example above can be written: Using systimer = system.timer; using winform = system.windows.form; // ... public class mainform: winform.form {systimer.timer checktimer; // with namespace using the same WinForm.Timer AnimateTimer ; // ......} We can see that such a code is much simpler. Global definition Before C # 2.0, there is still a very subtle problem when using the namespace. This is the method of finding the C # namespace. Consider the following example: Using system; namespace system {public class myconsole {public void writeline (string str) {system.console.writeline (STR); // pay attention to this line! }}}} Here I declare a system namespace in my namespace and simulate the console class. I hope it simulates the behavior of the console by calling the System.Console class. This program is no syntax problem, and it is still not possible to compile. Its main reason is that the C # namespace scope and common variable scope is similar, always look for the recent declaration, and internal declarations can overwrite external statements. Therefore, this code will win the bidders in the compiler when compiling the compiler will be prompted to find the class mynamespace.system.console - it tries to find the System.console class in my own namespace! Before C # 2.0, this issue is very headache for the designer of the class library. The only solution is to try not to use the name in the global namespace in your namespace. However, due to many class developers, there is a similar situation; and this will also cause the name that is not only a high-readable and simple name in his namespace, which undoubtedly hurts the logic of the language. Sex and simpleness. However, C # 2.0 introduces the Global keyword, allowing us to select the namespace from globally. Below this figure illustrates the status of the Global keyword from the .NET namespace: Figure 1: The position of the Global keyword in C # 1.x: Who's The Root? | - System (Namespace) | | | - Console (Class) | WriteLine (Method) | - INT32 (Struct) | - ... | - MyNamespace Namespace | - System ([Sub] Namespace) MyConsole (Class) In C # 2.0 Global (!!! ROOT !!!) | - System (Namespace) | | | - Console (Class) | WriteLine (Method) | - INT32 (STRUCT) | - ... | - MyNamespace Namespace | - System ([Sub] Namespace) MyConsole (Class) In this way, we can easily solve the conflict of namespace by using the Global keyword. The above example can also be rewritten as: Using system; namespace system {public class myconsole {public void writeline (string str) {global.system.console.writeline (STR); // pay attention to this line! }}}} Compiler instruction When we debug C # programs, some temporary variables are often declared to monitor the status and delete them after debugging. And when we declare this temporary variable, we usually get a lot of examples during the debugging process. Warning CS0168: The Variable 'Exp' Is Declared But Never Used Warning. However, we are very clear that such warnings are harmless. Similarly, many times we will also get some warnings, but we have to look for the wrong messages we need from a large number of harmless warnings. However, C # 2.0 provides us with a new compiler directive: Pragma Warning, making us to ban some of our confirmation warnings in a code (by specifying a warning number). Previously, this job can only be done by a particular compiler option (such as the Microsoft Visual C # compiler / NOWARN) or the corresponding IDE option (such as the corresponding options in the Idetribution page in Microsoft Visual Studio .NET 2003). Moreover, through the compilation environment hides the warning will result in all the corresponding warnings during compiling the entire project or the entire source file. If we only know that a warning in a code block is harmless, but for the other part of the code, we still want to see this warning message, this practice is powerless. At this time, we only hide the corresponding warnings in a code block through the Pragma Warning instruction. We can use the following code to ban the "unused parameters" described in the above example: Public class test {public void spsthod () {// The following compiler instruction prohibits the "unused parameters" warning: #pragma warning disable 0168 int tempstatus; // ... // The following compiler instruction Re-allowing a warning for "unused parameters": #pragma warning restore 0168}} Thus, when the compiler is compiled a SomeMethod () method, the "unused parameters" will not be generated, but the warning will still be generated when compiling other code segments, because we use the #pragma warning restore command to reopen The warning. Fixed size buffer Finally, in addition to some of the above features, C # 2.0 also provides a new feature of "Fixed Size Buffers". That is, you can declare a fixed size array in the structure like a C language, which is implemented by system.Runtime.CompilerServices.FixedBuffRibute attributes and Fixed keywords (see References page 26): [System.Runtime.compilerServices.Fexedbuffer] public struct buffer {public fixed char buffer [128]; But because the compiler I have not supported, there is no corresponding information, and I will not introduce it here.