New features of C # 7.0 (Quick Version)

Source: Internet
Author: User
"The new features of)c# 7" have taken a lot of time to introduce the 9 new features of C # 7.0, where I have a quick introduction to them based on project experience, with examples, so that we can get to know them in a short period.

Overall, these new features make C # 7.0 easier to write code with functional programming ideas, C # 6.0 has done a lot of work on this road, and C # 7.0 is a step closer!

Expression everywhere

In C # 6.0, you can use LAMBDA expressions for member methods and read-only properties, and the most depressing thing is why the set accessor for a property is not supported. Now, not only does the Set method support the use of lambda expressions, construction methods, destructors, and indexes all support the definition of lambda expressions.

Class somemodel{    private string internalvalue;    public string Value    {        get = = Internalvalue;        Set = Internalvalue = String. Isnullorwhitespace (value)? Null:value;}    }

outVariable

outA variable is a previously existing syntax, and C # 7 only allows it to put the declaration and use together, avoiding multiple lines of code. The most direct effect is that two statements can be completed with an expression. Here is an example of a simplified version of the class Key , which was used earlier by us to process ID values passed through HTTP get/post.

public class key{Public    string Value {get;}    Public Key (string key)    {        Value = Key;    }    public int intvalue    {        get        {            ///C # 6.0, you need to define intvalue in advance, but you do not need to initialize            //Although C # 6.0 can use LAMBDA expressions for read-only properties 
  
   //But there is no way to express int intvalue in an expression            ;            return int. TryParse (Value, out intvalue)? intvalue:0;}}}    
  

And in C # 7 it's easy.

Note that the out Var intvalue,//can even be used with VAR to declare the variable public int intvalue = = int for the inferred type. TryParse (Value, out var intvalue)? intvalue:0;

Tuple and structure

Used System.Tuple friends must be very uncomfortable with it Item1 , so there Item2 is no semantic name. However, C # 7.0 brings a semantic name, while also reducing the creation of tuples, which is no longer necessary Tuple.Create(...) . In addition, to use the new tuple feature to deconstruct, you need to introduce a NuGet package System.ValueTuple .

Install-package System.valuetuple

Of course, tuples are often used for methods that return multiple values. Also some people like out to use parameters to return, but even now can be out variable, I still do not agree with the wide use of out parameters.

The following example method is used to return a default time range (7 days from the beginning of today) for data retrieval.

The return type is a tuple containing two elements (DateTime Begin, DateTime end) Getdefaultdaterange () {    var end = DateTime.Today.AddDays (1);    var begin = End. AddDays ( -7);    This creates a tuple return with a pair    of parentheses (begin, end);}

Call this method to get the tuple, because the return value at the time of definition specifies the name of each data member, so getting the data from the tuple can be semantically, and of course it can still be used Item1 Item2 .

var range = Getdefaultdaterange (); var begin = range. Begin;    You can also begin = range. Item1var end = range. End;        You can also end = range. Item2

The above example can also be simplified without range this intermediate variable, which is used to understand the structure

VAR (begin, end) = Getdefaultdaterange ();

Creating tuples Here is an example of a return value, which is actually an expression that can be created anywhere in a tuple. The above example logic is simple and can be resolved with an expression. The following example shows a non-semantic return type declaration by the way.

The original (DateTime Begin, datetime End) Declaration is also no problem (datetime, DateTime) getdefaultdaterange ()    = ( DateTime.Today.AddDays (1). AddDays ( -7), DateTime.Today.AddDays (1));

Deconstruction Method deconstrct

The Deconstruction method allows any class (not just tuples) to be deconstructed by the defined parameters. And the magic is that the deconstruction method can be a member method, or it can be defined as an extension method.

public class size{Public    int Width {get;}    public int Height {get;}    public int Tall {get;}    public Size (int width, int height, int. tall)    {this        . width = width;        This. Height = height;        This. Tall = Tall;    }    deconstructed public void deconstruct defined as member method    (out int width, out int height)    {        width = width;        Height = height;    }}  public static class sizeext{    //The deconstruction of the extension method is defined public    static void deconstruct (this size size, out int width, out int Height, out int tall)    {        width = size. Width;        Height = size. Height;        Tall = size. Tall;}    }

Here's the code that uses deconstruction

var size = new Size (1920x1080, x, N), Var (w, h) = Size;var (×, y, z) = size;

SizeConstruction Method of transformation

Remember that the construction method mentioned earlier can be defined as a LAMBDA expression? Here is the transformation of the Size construction method using tuples and Lambda-I'm drunk!

public Size (int width, int height, int tall)    = (width, height, tall) = (width, height, tall);

Pattern matching

Pattern matching is currently supported is and switch . It's a big name on the tall one. The argument for a bit of grounding gas is that judging type by the way, define a specific type of reference, and be interested in adding some additional judgment.

For is speaking, it is time to define a variable and then initialize it, so the code like the original

Suppose the logic ensures that v here may be a string or intstring ToString (Object v) {    if (v is int) {        int n = (int) v;        Return n.tostring ("X4");    } else {        return (string) n;    }}

can be simplified into--well, just one step write the expression.

String ToString (Object v)    = = (v is int n)? n.tostring ("X4"): (string) v;

Of course, you might say that the previous one could also be simplified into an expression--well, don't delve into the question, okay? I just showed is the pattern match.

While switch pattern matching seems to be much more useful, let's take the example of ToString.

static string ToString (Object v) {    switch (v)    {        case int n when n > 0xFFFF:            //judgment type, matched to a value to be judged 
  
   return n.tostring ("X8");        case int N:            //judging type, here n sure <= 0xffff            return n.tostring ("X4");        case BOOL B:            return B? "On": "OFF";        Case NULL:            return null;        Default:            return v.tostring ();    }}
  

Note that the usage in the first branch above when is good.

Ref local variables and ref return values

This is already very close to the use of C + +. Although the official saying is that this can solve some security problems, but I personally still do not encounter its usage scenarios. If the design is good enough, and now added to the new features and deconstruction of the tuple, the individual thinks it can almost avoid the use out and ref .

Since it is useless, I do not say more, useful to the students to discuss!

Digital literal syntax enhancement

Here are two enhancements, one of which is the introduction 0b of the prefix binary number polygon syntax, and the other is the ability to group numbers arbitrarily in numeric literals _ . This is not a majority, for example, two.

const int mark_three = 0B11;            0x03const int long_mark = 0b_1111_1111;     0xffconst Double PI = 3.14_1592_6536

Local functions

The students who often write JavaScript are sure to experience it, and local function is a good thing. Of course, the biggest benefit it brings in C # is that some code is organized together. Before I used a large number of LAMBDA in my project instead of local functions, I can now replace them directly with local functions. LABMDA and local functions can do the same thing in most cases, but they still have some differences

    • For LAMBDA, the compiler has more to do with it. In short, it's much less efficient to compile.

    • LAMBDA is implemented by a delegate, the invocation process is more complex, local functions can be called directly. In short, local functions perform more efficiently.

    • LAMBDA must first be defined and reused, and local functions can be defined after use. It is said that there is a difference in the support for recursive algorithms

The more common place is in the enumerator function and the async function, because they are not actually executed immediately.

I'm mostly used to organize the code in my project. A local function, instead of a private function called only by one public API, is a good way to simplify the structure of a class, but the function body of the public API function is elongated. So many times I use inner classes instead of some private functions to organize the code. By the way, I'm not in favor of using the #region organization code.

Support for more async return types

If compared to the ES2017 async in JavaScript, C # is Task/Task<T> more like Promise a character. Do not envy JavaScript async support Promise like, now C # async also supports the Task as, as long as the implementation of the GetAwaiter method on the line.

The official provides an ValueTask example that can be introduced through NuGet:

Install-package System.Threading.Tasks.Extensions

One ValueTask of the more useful is that data types and tasks are compatible:

string cache; Valuetask<string> GetData () {    return cache = = null? New Valuetask<string> (Cache): New valuetask< String> (Getremotedata ());    Local function    async task<string> getremotedata ()    {        await task.delay (+);        Return "Hello async";    }}


"The new features of)c# 7" have taken a lot of time to introduce the 9 new features of C # 7.0, where I have a quick introduction to them based on project experience, with examples, so that we can get to know them in a short period.

Overall, these new features make C # 7.0 easier to write code with functional programming ideas, C # 6.0 has done a lot of work on this road, and C # 7.0 is a step closer!

Expression everywhere

In C # 6.0, you can use LAMBDA expressions for member methods and read-only properties, and the most depressing thing is why the set accessor for a property is not supported. Now, not only does the Set method support the use of lambda expressions, construction methods, destructors, and indexes all support the definition of lambda expressions.

Class somemodel{    private string internalvalue;    public string Value    {        get = = Internalvalue;        Set = Internalvalue = String. Isnullorwhitespace (value)? Null:value;}    }

outVariable

outA variable is a previously existing syntax, and C # 7 only allows it to put the declaration and use together, avoiding multiple lines of code. The most direct effect is that two statements can be completed with an expression. Here is an example of a simplified version of the class Key , which was used earlier by us to process ID values passed through HTTP get/post.

public class key{Public    string Value {get;}    Public Key (string key)    {        Value = Key;    }    public int intvalue    {        get        {            ///C # 6.0, you need to define intvalue in advance, but you do not need to initialize            //Although C # 6.0 can use LAMBDA expressions for read-only properties 
  
   //But there is no way to express int intvalue in an expression            ;            return int. TryParse (Value, out intvalue)? intvalue:0;}}}    
  

And in C # 7 it's easy.

Note that the out Var intvalue,//can even be used with VAR to declare the variable public int intvalue = = int for the inferred type. TryParse (Value, out var intvalue)? intvalue:0;

Tuple and structure

Used System.Tuple friends must be very uncomfortable with it Item1 , so there Item2 is no semantic name. However, C # 7.0 brings a semantic name, while also reducing the creation of tuples, which is no longer necessary Tuple.Create(...) . In addition, to use the new tuple feature to deconstruct, you need to introduce a NuGet package System.ValueTuple .

Install-package System.valuetuple

Of course, tuples are often used for methods that return multiple values. Also some people like out to use parameters to return, but even now can be out variable, I still do not agree with the wide use of out parameters.

The following example method is used to return a default time range (7 days from the beginning of today) for data retrieval.

The return type is a tuple containing two elements (DateTime Begin, DateTime end) Getdefaultdaterange () {    var end = DateTime.Today.AddDays (1);    var begin = End. AddDays ( -7);    This creates a tuple return with a pair    of parentheses (begin, end);}

Call this method to get the tuple, because the return value at the time of definition specifies the name of each data member, so getting the data from the tuple can be semantically, and of course it can still be used Item1 Item2 .

var range = Getdefaultdaterange (); var begin = range. Begin;    You can also begin = range. Item1var end = range. End;        You can also end = range. Item2

The above example can also be simplified without range this intermediate variable, which is used to understand the structure

VAR (begin, end) = Getdefaultdaterange ();

Creating tuples Here is an example of a return value, which is actually an expression that can be created anywhere in a tuple. The above example logic is simple and can be resolved with an expression. The following example shows a non-semantic return type declaration by the way.

The original (DateTime Begin, datetime End) Declaration is also no problem (datetime, DateTime) getdefaultdaterange ()    = ( DateTime.Today.AddDays (1). AddDays ( -7), DateTime.Today.AddDays (1));

Deconstruction Method deconstrct

The Deconstruction method allows any class (not just tuples) to be deconstructed by the defined parameters. And the magic is that the deconstruction method can be a member method, or it can be defined as an extension method.

public class size{Public    int Width {get;}    public int Height {get;}    public int Tall {get;}    public Size (int width, int height, int. tall)    {this        . width = width;        This. Height = height;        This. Tall = Tall;    }    deconstructed public void deconstruct defined as member method    (out int width, out int height)    {        width = width;        Height = height;    }}  public static class sizeext{    //The deconstruction of the extension method is defined public    static void deconstruct (this size size, out int width, out int Height, out int tall)    {        width = size. Width;        Height = size. Height;        Tall = size. Tall;}    }

Here's the code that uses deconstruction

var size = new Size (1920x1080, x, N), Var (w, h) = Size;var (×, y, z) = size;

SizeConstruction Method of transformation

Remember that the construction method mentioned earlier can be defined as a LAMBDA expression? Here is the transformation of the Size construction method using tuples and Lambda-I'm drunk!

public Size (int width, int height, int tall)    = (width, height, tall) = (width, height, tall);

Pattern matching

Pattern matching is currently supported is and switch . It's a big name on the tall one. The argument for a bit of grounding gas is that judging type by the way, define a specific type of reference, and be interested in adding some additional judgment.

For is speaking, it is time to define a variable and then initialize it, so the code like the original

Suppose the logic ensures that v here may be a string or intstring ToString (Object v) {    if (v is int) {        int n = (int) v;        Return n.tostring ("X4");    } else {        return (string) n;    }}

can be simplified into--well, just one step write the expression.

String ToString (Object v)    = = (v is int n)? n.tostring ("X4"): (string) v;

Of course, you might say that the previous one could also be simplified into an expression--well, don't delve into the question, okay? I just showed is the pattern match.

While switch pattern matching seems to be much more useful, let's take the example of ToString.

static string ToString (Object v) {    switch (v)    {        case int n when n > 0xFFFF:            //judgment type, matched to a value to be judged 
  
   return n.tostring ("X8");        case int N:            //judging type, here n sure <= 0xffff            return n.tostring ("X4");        case BOOL B:            return B? "On": "OFF";        Case NULL:            return null;        Default:            return v.tostring ();    }}
  

Note that the usage in the first branch above when is good.

Ref local variables and ref return values

This is already very close to the use of C + +. Although the official saying is that this can solve some security problems, but I personally still do not encounter its usage scenarios. If the design is good enough, and now added to the new features and deconstruction of the tuple, the individual thinks it can almost avoid the use out and ref .

Since it is useless, I do not say more, useful to the students to discuss!

Digital literal syntax enhancement

Here are two enhancements, one of which is the introduction 0b of the prefix binary number polygon syntax, and the other is the ability to group numbers arbitrarily in numeric literals _ . This is not a majority, for example, two.

const int mark_three = 0B11;            0x03const int long_mark = 0b_1111_1111;     0xffconst Double PI = 3.14_1592_6536

Local functions

The students who often write JavaScript are sure to experience it, and local function is a good thing. Of course, the biggest benefit it brings in C # is that some code is organized together. Before I used a large number of LAMBDA in my project instead of local functions, I can now replace them directly with local functions. LABMDA and local functions can do the same thing in most cases, but they still have some differences

    • For LAMBDA, the compiler has more to do with it. In short, it's much less efficient to compile.

    • LAMBDA is implemented by a delegate, the invocation process is more complex, local functions can be called directly. In short, local functions perform more efficiently.

    • LAMBDA must first be defined and reused, and local functions can be defined after use. It is said that there is a difference in the support for recursive algorithms

The more common place is in the enumerator function and the async function, because they are not actually executed immediately.

I'm mostly used to organize the code in my project. A local function, instead of a private function called only by one public API, is a good way to simplify the structure of a class, but the function body of the public API function is elongated. So many times I use inner classes instead of some private functions to organize the code. By the way, I'm not in favor of using the #region organization code.

Support for more async return types

If compared to the ES2017 async in JavaScript, C # is Task/Task<T> more like Promise a character. Do not envy JavaScript async support Promise like, now C # async also supports the Task as, as long as the implementation of the GetAwaiter method on the line.

The official provides an ValueTask example that can be introduced through NuGet:

Install-package System.Threading.Tasks.Extensions

One ValueTask of the more useful is that data types and tasks are compatible:

string cache; Valuetask<string> GetData () {    return cache = = null? New Valuetask<string> (Cache): New valuetask< String> (Getremotedata ());    Local function    async task<string> getremotedata ()    {        await task.delay (+);        Return "Hello async";    }}
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.