Main constructor
Automatic attribute initialization expressions are especially useful in conjunction with the main constructor. The main constructor provides a way to reduce the complexity of common object patterns. This feature has been significantly improved since May. Updates include:
- Optional implementation body of the main constructor: this will support the validation and initialization of primary constructor parameters that were not supported previously.
- Cancel Field parameter: Declares a field through the main constructor parameter. (It is the right decision not to have this feature rolled out as defined, because it no longer enforces adherence to specific naming conventions in a way that is inconsistent with C #.) )
- Expression body functions and properties are supported (discussed later in this article).
With the widespread use of Web services, multi-tier applications, data Services, Web APIs, JSON, and similar technologies, a common form of class is data transfer objects (DTOS). DTOs typically do not implement too much functionality, but instead focus on simplifying the data store. Its focus on simplicity makes the main constructor a very new attraction. For example, take a look at the fixed Pair data structure shown in this example:
struct Pair<t>(t first, T second) { publicget;} = First ; Public get; } = second; // equality operator...}
The constructor defines the Pair (string first, string second) that has been merged into the class declaration. This specifies the constructor parameters as first and second (both type T). These parameters are also referenced in the property initialization expression, and the parameters are assigned to their corresponding properties. When you find the simplicity of such a definition, support for immutability, and an essential constructor (all attribute/field initialization expressions), you will see how it helps you write code correctly. This leads to significant improvements in common patterns that previously required unnecessary verbosity levels.
The main constructor body specifies the operation to be performed on the main constructor. This will help you implement equivalent functionality that is typically achievable on the constructor on the main constructor. For example, the next step in improving the reliability of a pair<t> data structure might be to provide property validation. This type of validation ensures that the null value of the Pair.first will be invalid. Now, CTP3 includes a main constructor body (an undeclared constructor body), as shown in Figure 4 .
implementing the main constructor bodystructPair<t>(t first, T second) {{if(First = =NULL)Throw NewArgumentNullException (" First"); First= First;//note:not working in CTP3 } PublicT First {Get; };//note:results in compile error for CTP3 PublicT Second {Get; } =second; Public intCompareTo (t first, T second) {returnFirst.compareto (first) +Second.compareto (second); }//equality operator ...}
For the sake of clarity, I put the main constructor body in the first member of the class. But that's not what C # requires. The main constructor body can be displayed in any order related to other class members.
Another feature of the read-only property, although not functional in CTP3, allows you to assign these properties directly from within the constructor (for example, first = first). This is not limited to the main constructor, but also applies to all constructor members.
An interesting result of the support for automatic property initialization expressions is that it resolves a number of scenarios that would require explicit field declarations in earlier versions. It does not solve one of the most obvious problems, that is, the need to validate the setter. On the other hand, there is almost no need to declare read-only fields. Now, whenever you declare a read-only field, you can declare a read-only automatic property as private whenever you want the encapsulation level.
The CompareTo method has parameter first and second, which seems to duplicate the parameter name of the main constructor. Because the primary constructor name is within the scope of an automatic property initialization expression, first and second do not seem to be clear. Fortunately, the reality is not so. Scope rules are based on different dimensions, which you did not see previously in C #.
Before C # 6.0, scopes are always determined by the placement of variable declarations within the code. Parameters are bound in the method of their help declaration, the fields are bound in the class, and the variables declared in the IF statement are bound by the condition body of the IF statement.
In contrast, the main constructor parameter is bound by time. The main constructor parameter is the active state only when the primary constructor is executed. This time range is evident in the case of the main constructor body. It may not be obvious for an automatic property initialization expression.
However, similar to a field initialization expression that is executed as part of a class initialization expression in C # 1.0+, an automatic property initialization expression is implemented in the same way. In other words, the scope of the primary constructor parameter is bound to the life cycle of the class initialization expression and the main constructor body. Any reference to the main constructor parameter in an automatic property initialization expression or outside the main constructor body will result in a compilation error.
There are several other concepts related to the main constructor that need to be kept in mind. Only the primary constructor can call the base constructor. You can do this using the basic (context) keyword followed by the main constructor declaration:
class usbconnectionexception ( string message, Exception innerexception, Hiddeviceinfo Hiddeviceinfo): Exception (message, innerexception) { publicget; } = Hiddeviceinfo;}
If you specify a different constructor, the constructor call chain must last call the main constructor. This means that the primary constructor cannot have this initialization expression. Assuming that the primary constructor is also not a default constructor, all other constructors must have these initialization expressions:
Public class Patent (stringstring yearofpublication) { public patent (string string Yearofpublication, IEnumerable<string> inventors) ... This (title, yearofpublication) { Inventors.addrange (inventors); }}
Hopefully, these examples will help demonstrate that the main constructor simplifies C #. With the main constructor, there is an opportunity to perform simple tasks in a simple way, rather than performing simple tasks in a complex way. It also occasionally causes the class to contain multiple main constructors and call chains, which makes the code not easy to read. If you encounter a case where the main constructor syntax makes your code look more complex than simplifying your code, do not use the main constructor. For all enhancements to C # 6.0, do not use this feature if you have a feature that you do not like, or if a feature makes your code not easy to read.
Expression body functions and expression properties
The expression body function is another form of syntax refinement in C # 6.0. Some functions do not include the body of the statement, but are implemented in the form of a function declaration followed by an expression.
For example, you can add an override of the ToString method to the Pair<t> class:
Public Override string string. Format ("{0}, {1}", First, Second);
There is nothing completely changed in the expression body function. Like most of the features in C # 6.0, they are designed to provide simplified syntax for simple situations. Of course, the return type of an expression must match the return type defined in the function declaration. In this case, ToString returns a string that is the same as the result returned by the function implementation expression. Methods that return void or Task should be implemented by an expression that also does not return any results.
Expression body simplification is not limited to functions, you can also use expressions to implement read-only (getter-only) Properties-expression properties. For example, you can add a Text member to the Fingerprint class:
Public string Text = string. Format ("{0}: {1}-{2} ({3})", TimeStamp, Process, Config, User);
Other features
There are some features that are no longer scheduled for C # 6.0 implementations:
- The Indexed property operator ($) is no longer available and is not implemented for C # 6.0.
- Although the index member syntax is expected to return in a later version of C # 6.0, it does not work in CTP3:
var Cpphelloworldprogram = Span style= "color: #0000ff;" >new dictionary<int , string >{[ 10 ] = " main () { " 20 ] = " printf (\ "Hello, world\") " ,[ Span style= "color: #800080;" >30 ] = " };
The field parameters in the Main constructor no longer belong to C # 6.0.
- Digital separators in binary numeric text and digital text ('_') are not yet confirmed until the official release.
Original source: http://msdn.microsoft.com/zh-cn/magazine/dn802602.aspx
C # 6.0 new features (iii)