New feature summary _c# tutorial in c#7.0

Source: Internet
Author: User
Tags case statement constant data structures garbage collection microsoft c

The following is a description of all the planned language features in C # 7.0. With the release of Visual Studio "Preview" version 4, most of these features will be active. Now is the time to show these features, and you tell them to tell us what you think!

C#7.0 adds a number of new features and focuses on data consumption, simplifying code and performance improvements. Perhaps the biggest feature is ganso and pattern matching, and the progenitor can easily have multiple return results, and model matching can simplify code based on the "shape" of the data. We hope to combine them to make your code more concise and efficient, and to make you happier and more productive.

Please click on the feedback button at the top of the Visual Studio window to tell us what features you don't expect or what you think about promoting these features. Many other features are not implemented in the Preview 4 release. Next I will describe some of the features that will work in the final version of our release, and some features that will be removed once the machine is not functioning. I am also in favor of making changes to these plans, especially as a result of the feedback we receive from you. When the final release is released, some of these features will change or be deleted.

If you are curious about the design process of these features, you can find a lot of design notes and discussions on Roslyn GitHub site.

Hope c#7.0 can bring you happiness!

Output variables

In the current C #, the use of output parameters is not as convenient as we think. Before you call a method without an output parameter, you must first declare a variable and pass it to it. If you do not initialize these variables, you cannot use Var to declare them unless you specify the complete type first:

public void Printcoordinates (point P)
{
int x, y;//have to ' Predeclare '
p.getcoordinates (out x, out y);
WriteLine ($ "({x}, {y})");
}

In c#7.0, we are adding output variables and declaring a variable that can be passed the output argument:

public void Printcoordinates (point P)
{
p.getcoordinates (out int x, out int y);
WriteLine ($ "({x}, {y})");
}

Note that variables are within the bounds of the enclosing block, so you can use them later. Most types of declarations do not establish their own scope, so the variables declared in them are usually introduced into the enclosing scope.

Note: In Preview 4, the applicable scope rules are more stringent: the scope of the output variables is the statement that declares them, so the previous example will not work until the next version is released.

Because the output variables are declared directly as arguments passed to the output parameters, the compiler usually tells them the type to be used (unless there is a conflict overload), so it is better to use VAR instead of declaring them:

P.getcoordinates (out Var x, out Var y);

One common use of output parameters is try mode, where a Boolean return value indicates success, and the output parameter carries the resulting result:

public void Printstars (string s)
{
if (int). TryParse (s, out var i)) {WriteLine (New string (' * ', i));}
else {WriteLine ("Cloudy-no stars tonight!");}

Note: I only use the IF statement to define it here, so Preview 4 can handle this very well.

We plan to allow a * as the form of "wildcard" as an output parameter, which will allow you to ignore the parameters you do not care about:

P.getcoordinates (out int x, out *); I only care about X

Note: It is not certain whether the wildcard character will be included in the c#7.0.

Pattern matching

C # 7.0 introduces the concept of schemas. In abstract terms, a pattern is a syntactic element that can be used to test whether a data has a certain "shape" and, when applied, extracts valid information from the value.

Examples of patterns in c#7.0:

A constant pattern in the form of C (c is a constant expression in C #), you can test whether the input equals C

T X-type pattern (T is a type, x is an identifier), you can test whether the input is a T type, and if so, the input value is extracted to the new variable x of type T

var x is the Var pattern (x is an identifier), it always matches, and simply stores the input value in a new variable x with its original type.

This is just the beginning-the pattern is a new type of language element in C #. In the future, we want to add more patterns to C #.

In c#7.0, we are strengthening two existing schema-structured language structures:

The is expression now has a right-hand-side pattern, not just a type

The case statement in the switch statement can now use a match pattern, not just a constant value

In future versions of C #, we may be adding more patterns to be used.

is expression with pattern

The following is an example of an IS expression that took advantage of the constant pattern and the type pattern:

public void Printstars (object o)
{
if (o. null) return;//constant pattern "null"
if (!) o is int i)] return; Type pattern "int i"
WriteLine (New string (' * ', i));
}

As you can see, the pattern variables (the variables introduced by the pattern) are similar to the output variables described earlier, and they are declared in the middle of an expression and used in the nearest scope. As with output variables, the pattern variable is variable.

Note: As with output variables, the strict scope rule applies to preview 4.

Patterns and try methods can work well together:

 
 

Switch statement with pattern

We are summarizing the Switch statement:

• You can set any type of Switch statement (not just the original type)

• Patterns can be used in case statements

Case statements can have special conditions

The following is a simple example:

Switch (Shape)
{case
Circle C:
WriteLine ($ "Circle with radius {C.radius}");
break;
Case Rectangle s when (s.length = = s.height):
WriteLine ($ "{s.length} x {s.height} square");
break;
Case Rectangle R:
WriteLine ($ "{r.length} x {r.height} Rectangle");
break;
Default:
WriteLine ("<unknown shape>");
break;
Case NULL:
throw new ArgumentNullException (nameof (Shape));
}

There are a few things to note about the new extension of the switch statement:

The order of the case statements now becomes important: As with catch statements, the scope of the case statement can now intersect, and the first match will be selected. Also, like a catch statement, the compiler helps you by removing the apparently inaccessible case. Before that, you don't even have to tell the order of judgment, so it's not a huge change in the use of case statements.

• The default statement is finally judged: although a null case statement appears before the last statement, it is also tested before the default statement is selected. This is compatible with the existing Switch semantics. However, good practice usually puts the default statement at the end.

switch does not go to the last NULL statement: This is because the example of the current is expression has a type match and does not match to null. This ensures that null values are not accidentally matched by any type pattern; you have to be more specific about how to handle them (or discard them and use the default statements).

Introducing a pattern variable through a case: the label is only within the corresponding Switch range.

META Group

This is a common pattern for returning multiple values from a method. The options currently available are not the best:

• Output parameters: Awkward to use (even with the improvements mentioned above), they do not work with asynchronous methods.

system.tuple<...> return type: Redundant use and request allocation of a tuple object.

• The custom transport type of the method: for the type, there is a large amount of code overhead, which is intended only to temporarily combine some values.

• Return anonymous types by dynamic return type: High performance overhead, no static type checking.

To do better at this point, c#7.0 the added tuple type and tuple text:

(String, String, String) Lookupname (Long ID)//tuple return type
{
...//retrieve, middle and last from data storage return
(FI RST, middle, last); Tuple literal
}

This method effectively returns three strings, contained in a tuple value as an element.

The invocation of this method receives a tuple and can access its elements individually:

var names = Lookupname (ID);
WriteLine ($ "found {names.") ITEM1} {names. ITEM3}. ");

Item1 are the default names for tuple elements and can be used all the time. But they don't have descriptive, so you can choose to add better:

(String A, string middle, string last) Lookupname (Long ID)//tuple elements have names

Now the recipient of the tuple has more than one descriptive name available:

var names = Lookupname (ID);
WriteLine ($ "found {Names.first} {names.last}.");

You can also specify the element name directly in the tuple literal:

Return (First:first, Middle:middle, last:last); Named tuple elements in a literal

You can generally assign a tuple type a number of unrelated names: as long as each element is configurable, the tuple type can be easily converted to another tuple type. There are also some restrictions, especially on the tuple text, that is, common and alarm errors, such as inadvertently exchanging element names, there will be errors.

Note: These restrictions are not yet implemented in Preview 4.

Tuples are value types, and their elements are public and variable. They have equal values, and if all the elements are equal (and have the same hash value), then the two tuples are equal (and have the same hash value).

This allows tuples to be useful when multiple values need to be returned. For example, if you need a dictionary of multiple key values, use a tuple as your key value, and everything will be fine. If you need a list of multiple values in each location, using a tuple for a list search will work well.

Note: Tuples are dependent on a set of basic types, but are not included in Preview 4. To make this feature work, you can get them by NuGet:

• Right-click an item in Solution Explorer and select "Managed NuGet package ..."

• Select the "Browse" tab, select "Include prerelease" and select "Nuget.org" as "Package source"

• Search for "system.valuetuple" and install it.

Deconstruction

Another way to consume tuples is to deconstruct them. A deconstruction declaration is a syntax that splits a tuple (or other value) into parts and assigns it separately to a new variable:

(String A, string middle, string last) = Lookupname (ID1); Deconstructing declaration
WriteLine ($ "found {i} {last}.");

In the deconstruction declaration, you can use Var to declare a separate variable:

(Var, var middle, var last) = Lookupname (ID1); var inside

Or put a separate VAR as an abbreviation outside the parentheses:

var (A, middle, last) = Lookupname (ID1); var outside

You can also use the deconstruction task to solve the existing variables

(middle, last) = Lookupname (ID2); Deconstructing Assignment

Deconstruction is not just applied to tuples. Any type can be refactored as long as it has the deconstruction method of (an instance or an extension):

public void deconstruct (out T1 x1, ..., out Tn xn) {...}

An output parameter constitutes an understanding of the value in the structure result.

(Why does it use arguments instead of returning a tuple?) This is to allow you to have multiple overloads for different values.

Class Point
{public
int × {get;}
public int Y {get;}
public point (int x, int y) {x = x; y = y; Public
void deconstruct (out int x, out int y) {x = x; y = y;}
}
(Var myx, var myy) = GetPoint (); Calls deconstruct (out of MYX, out myy);

This is a common pattern that encompasses the construction and deconstruction in a symmetrical way.

For output variables, we plan to add wildcard characters to the refactoring to simplify the variables you don't care about:

(Var myx, *) = GetPoint (); I only care about MYX

Note: Whether the wildcard character will appear in the c#7.0 is still unknown.

Local functions

Sometimes, an auxiliary function can work within a single function. Now, you can declare such a function inside other functions as a local function:

public int Fibonacci (int x)
{
if (x < 0) throw new ArgumentException ("Less negativity please!", nameof (x)); 
   
    return Fib (x). Current;
(int current, int previous) Fib (int i)
{
if (i = = 0) return (1, 0);
var (p, pp) = Fib (i-1);
return (P + pp, p);
}



   

The parameters and local variables within the closed range are available within the local function, just as they are in a lambda expression.

For example, iterative method implementations typically require a non iterative encapsulation method to check the arguments at call time. (The iterator itself does not start running until MoveNext is invoked). Local functions are ideal for scenarios like this:

Public ienumerable<t> filter<t> (ienumerable<t> source, func<t, bool> Filter)
{
if ( Source = = null) throw new ArgumentNullException (nameof (source));
if (filter = = null) throw new ArgumentNullException (nameof (filter));
return iterator ();
Ienumerable<t> iterator ()
{
foreach (var element in source) 
{
if (filter (element)) {yield return element; }
}
}
}

If the iterator has a private method passed to the filter, the iterator becomes available even if there are no parameter checks when the other member accidentally uses the iterator. In addition, the same arguments are taken as filters to replace the parameters within the range.

Note: In Preview 4, the local function must be declared before it is invoked. This restriction will be released so that local functions can be invoked when they are read from the definition assignment.

Text improvements

c#7.0 allow _ to appear as a number separator:

var d = 123_456; var x = 0xab_cd_ef;

You can add _ to any number to increase readability, and they have no effect on the value.

In addition, c#7.0 introduces binary text so that you can specify binary patterns without having to understand hexadecimal.

var B = 0b1010_1011_1100_1101_1110_1111;

Reference returns and local references

Just as passing arguments by reference in C # (using a reference modifier), you can now return parameters by reference, as well as storing parameters in the same way as local variables.

Public ref int find (int number, int[] numbers)
{for
(int i = 0; i < numbers. Length; i++)
{
if (numbers[i] = = number) 
{return
ref numbers[i];//Return of storage location, not the Value
   }
}
throw new IndexOutOfRangeException ($ "{nameof (number)} not found");
Int[] Array = {1, -39, 0, 7, -12};
ref int place = ref Find (7, array); Aliases 7 ' s place in the array place
= 9;//replaces 7 with 9 in the array
WriteLine (array[4]);//Prints 9

This is a good way to bypass placeholders and get into large data structures. For example, a game might save its data in a large, pre-configured array structure (to avoid a halt to the garbage collection mechanism). Method can return a direct reference to a struct, and it can be read and modified by its caller.

There are also some restrictions to ensure security:

• You can only return a reference to "safe return": one that is passed to you and one that refers to the reference in the object.

• Local references are initialized to a local store and cannot point to another store.

Asynchronous return type

Until now, C # 's asynchronous methods must return to Void,task or task<t>. c#7.0 allows other types to be defined in such a way that they can be returned from a method, because they can define other types in the way that the asynchronous method is returned.

For example, we plan to create a valuetask<t> structure type of data. It is established to prevent the results of asynchronous runs from being allocated to task<t> in situations that are available when waiting. For asynchronous scenarios where buffers are designed in many instances, this can significantly reduce the number of allocations and significantly improve performance.

Note: The asynchronous return type has not been provided in Preview 4.

More Expression bodied members:

Expression bodied's methods and properties are a huge boost to C # 6.0. C # 7.0 adds accessors, structs, and finalizers to the list of expression bodied events.

Class Person
{
private static concurrentdictionary<int, string> names = new Concurrentdictionary<int, String> ();
private int id = GetId ();
Public person (string name) => names. TryAdd (ID, name); Constructors
~person () => names. Tryremove (ID, out *); Destructors public
string Name
{get
=> names[id];//getters
set => names[id] = value;//Setter S
}
}

Note: These additional expression bodied members are not yet available in Preview 4.

This is an example of community sharing, not provided by the Microsoft C # compilation team, or open source!

Throw expression

Throwing an exception in the middle of an expression is easy: just call a method for your own code! But in c#7.0, we allow an expression to be thrown anywhere:

Class person
{public
string Name {get;}
Public person (string name) => name = name?? throw new ArgumentNullException (name);
public string Getfirstname ()
{
var parts = name.split ("");
Return (parts. Length > 0)? Parts[0]: Throw new InvalidOperationException ("No name!");
}
public string Getlastname () => throw new NotImplementedException ();
}

The Note:throw expression is not yet available in preview 4.

The above is a small set to introduce the new characteristics of the c#7.0, I hope to help you, if you have any questions please give me a message, small series will promptly reply to everyone. Here also thank you very much for the cloud Habitat Community website support!

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.