Effective C #: 3. Try to compatibility with customized types with public language norms
Chen Ming Microsoft C # /. Net Asia MVP
Difficult: 5/10 Terms 2
A sunny morning, you are a hundred times, sitting in front of your computer, ready to start a busy job. Today's work content is to write a program that automatically sends a confirmation message according to the user's order - there is no doubt that the tool is your most handful C #.
At this time, you suddenly think that your colleague in Visual Basic.NET has written a small component used to send an email. Why don't you use ready-made components to simplify your work? Isn't it to say that one of the advantages of .NET is to make a quick and fast cross-language component reuse? It looks a quite good idea.
Get this component and related documentation does not cost anything, but a piece of text on the document makes you like a five-mile fog: "... After setting the email address, call the Mail class object's Mail method sends mail ...". It seems that the name of the function is better with Send, which is still still. Is the Mail method of the Mail class? Is it a constructor? how can that be possible? Or is it wrong with the document?
Confused, not good, not to look at some of the grammar of Visual Basic.Net: You can define classes in VB.NET, define the constructor of the class, but its grammar and the C # large phase mirror - VB.net is not class name Instead, use the keyword NEW to define the constructor, as shown below:
'VB.Net Definition for Class Mail
Public Class Mail
Sub new ()
'Here Is The Constructor!
End Sub
'Other Type MEMBERS
SUB mail ()
'This is only a member function
'NOT CLASS CONSTRUCTOR
End Sub
END CLASS
Due to the use of New to define the constructor, VB.NET can define a member function that is the same name as the same name, and this is absolutely not possible in C #. After compiling, the name of the constructor in the metadata is .ctor, this name is apparent and the type name does not conflict. Therefore, the member function name cannot be the same as the type name of the .NET platform, but the limit of the C # syntax.
So, what is the cross-language interaction and reuse on the .NET platform? Before understanding the support for cross-language interaction, there is a need to learn the following two concepts: Public Type System (CTS, Common Type System) and Public Language Specification (CLS, Common Language Specification).
.NET builds above a rich and huge type of system, one of the design purposes of this type is to support the features of existing programming languages as much as possible, from process language to object-oriented language, even Functional languages such as Lisp (if you have never touched the functional language, then .NET supported TAILCALL function call mode may surprise you). Microsoft is natively named this type of system for this type of .NET building, that is, CTS.
Since the CTS has such a complete definition, it is constructed to "assemble language" MSIL - "assembly language" MSIL - with very powerful expression, such as using MSIL, can be defined in class All global functions and variables (you don't have a mistake, .net does support global variables), support only the reload of the return value type (can be found in the terms X), even support Define static member variables and methods for interfaces.
Furthermore, it is MSIL's rich expression ability, so that .NET can be included in the .NET framework. From the C (Managed C Extension), Visual Basic (VB.NET) to Eiffel, or even a scripting language like JScript.net and Python, or even a scripting language like JScript.net and Python, and. There are more than a dozen languages, and there are still new members to join this group. You can use your well-known program language to develop your well-known program language on a new .NET platform, which is undoubtedly a great gospel for programmers in reality. However, we can only say ".NET is a environment that supports multiple languages", and interactions between different languages still have no talk. Although unified type information storage form and intermediate code, different language expressions are endless, and supported grammar is also different. This makes different .NET programming language exposed CTS function subsets are not exactly the same. For example, C # support operator overload does not directly correspond to the calling method in VB.NET, and the so-called TAILCALL function call mode of the functional language is impossible to be supported by other .NET language.
To this end, .NET also defines the public language specification (CLS, Common Language Specification) based on CTS. Unlike CTS, CLS does not pursue functionality, but focuses on a subset of the CTS that must be implemented in various .NET languages, and how to use the functionality in the program. Since the starting point of the CLS is interactive between different languages, it applies only to types and members of the external accessible accessible, such as the type of public / protected, and members of public / protected, as PUBLIC / Protected member variables, such as the type of public / protected, from the type of access to the class. function. Just make sure that these types that can be accessed from class sets and their members in accordance with the CLS specification, it is possible to ensure that the class libraries designed can be used in almost all .NET program language, thereby implementing the .NET's cross-language interaction capabilities. . As for other private types and their members, they can give full play to the expressive ability to express their specific languages, and they do their best to make maximum simplified programming. For example, VB.NET directly supports the evening binding of the COM object, and the same function is not easy in other .NET language, such as C #, then consider writing COM objects by VB.NET. The class set, other parts of the application with C #, as long as the interfaces exposed, the modules can be easily achieved between the modules. Seamless integration.
The complete CLS specification is very trivial, and the squares design of the .NET program design (fortunately, it is not necessary to keep these terms to ensure that your program meets the CLS specification, the compiler can complete most of the inspection work, will be more detailed introduction). The following table lists the partial rules of CLS, familiar with these more common rules will help more clearly understand the meaning of CLS:
About naming
Character and case
Can't distinguish between only two identifies in different cases
Uniqueness of identification
In addition to overload, the same name is not available in the resolution space.
Any two identification
Function declaration
The parameters and return value types used in the function declaration must be compatible with CLS
Type
Built-in type
In the .NET built-in type, only byte, int16, int32, int64, single, double, boolean, char, decimal, intptr, and string are CLS compatible *
Closed characteristics
All members of interfaces and abstract base classes with CLS must ensure compatible with CLS
Constructor call
Before accessing any class members, the constructor of the subclass must first adjust the constructor of the parent class.
Type member
Overload
Functions, attributes, and events cannot be overloaded only by the return value type
* These types correspond to: Byte, Short, Int, long, float, double, bool, char, decimal, and string here only part of the CLS specification is only a minimum part of the CLS specification. The programmer is required to remember that these cumbersome rules seem to be unrealistic, so the compilers of various .NET languages provide CLS compatibility detection. As long as you add CLSCompliantAttribute feature for those who wish to compatibility with CLS specification, the compiler will help you check whether the code meets the CLS specification and gives the necessary error messages.
For example, you can try to compile the following C # code:
//clstest.cs
Using system;
[Assembly: CLSCompliant (TRUE)]
Namespace Effective.csharp.chapter {
Public class myclass {
// uint type is not compatible with CLS
Public uint getMydata () {
// ... the specific implementation of the function
}
}
}
The compiler produces the following error message:
CLSTEST.CS (7,10): Error CS3002: Return Type of
'Effective.csharp.chapter3.myclass.getMydata ()' Is Not CLS-Compliant
And if the access setting of the getMyData function is changed to Private or Internal, the compiler will not report a similar error.
In this way, there is a help of the compiler, make sure that the type you designed and CLS is easily easy. However, some types of libraries were originally unable to be in accordance with CLS-compatible standards (the examples mentioned to this chapter), and you are just the user of this class library, when these class libraries touch the dead end of different language functions Isn't we doing it? In fact, .NET provides an exceptional powerful type reflection (the only type and its members can be used to access those programming language power, such as the examples mentioned in this chapter, you can use type reflection to call MAIL method:
// ... use reflection to invoke mail.mail
Mail mail = new mail ("someone@somewhere.com");
// ... Initialize Mail Object
TYPE T = TypeOf (Mail);
// Invoke Mail Method
T.invokemember ("Mail", BindingFlags.InvokeMethod,
NULL, MAIL, New Object [] {});
Obviously, the functionality and readability of the type reflection is greatly reduced using the performance and readability of the type reflected by the type. Therefore, as the designer of the component, we should try to ensure that the type definition of the component is compatible with CLS. (Finish)
* This article is originally original, please do not reprint without the author's license.