Detailed c#7.0 new features

Source: Internet
Author: User

1. Out variable (out variables)

Before we used out variables that had to be declared before use, C # 7.0 gave us a more concise syntax of "inline declaration when used." As shown below:

1   var input = ReadLine (); 2   if (int). TryParse (input, out var result)) 3   {4       WriteLine ("The number you entered is: {0}", result); 5   }6   else7   {8       WriteLine ("Cannot parse input ..."); 9   }

After compiling the above code:

1   int num; 2   string s = Console.ReadLine (); 3   if (int. TryParse (s, out num)) 4   {5       Console.WriteLine ("The number you entered is: {0}", num); 6   } 7   Else 8   {9       Console.WriteLine ("Cannot parse input ...");   

Principle Analysis: The so-called "inline declaration" after compiling is the original writing, but now by the compiler to complete.

Note: When you make an inline declaration, you can directly state the type of the variable or write an implicit type, because the Out keyword is decorated with a local variable.

2. Tuples (tuples)

Tuple (tuple) is available in. Net 4.0, but tuples have some drawbacks, such as:

1) A Tuple affects the readability of the code because its property name is: Item1,item2. 。

2) The Tuple is not lightweight enough because it is a reference type (Class).

Note: The above-mentioned Tuple is not lightweight enough, in a sense or a hypothesis, that is, assuming that the allocation operation is very much.

The tuples in C # 7 (ValueTuple) address these two drawbacks:

1) ValueTuple support for semantic field naming.

2) ValueTuple is a value type (Struct).

1. How do I create a tuple?

1   var tuple = (1, 2);                           Create tuples with syntactic sugars 2   var tuple2 = valuetuple.create (1, 2);         Create a tuple using the static method "create" 3   var tuple3 = new Valuetuple<int, int> (1, 2);  Use the new operator to create a tuple 4   5   WriteLine ($ "first:{tuple. ITEM1}, Second:{tuple. ITEM2}, the above three methods are equivalent. ");

Rationale: The above three methods are ultimately used to create an instance using the new operator.

2. How do I create a tuple named for a field?

1   //left specifies the field name 2   (int one, int) tuple = (1, 2); 3   WriteLine ($ "first:{tuple.one}, Second:{tuple.two}"); 4
   5   //Right Specify field name 6   var tuple2 = (one:1, two:2); 7   WriteLine ($ "first:{tuple2.one}, Second:{tuple2.two}"); 8
   9   //left and right both sides specify the field name at ten   (int one, int two) Tuple3 = (first:1, second:2);    /* There will be a warning: because the target type (XX) has specified a different name because the tuple name is ignored, xxx */11   WriteLine ($ "first:{tuple3.one}, Second:{tuple3.two}");

Note: Both sides specify the field name, and the field name on the left overrides the field name on the right (one by one corresponds).

Principle Analysis: The tuple named after the field is compiled with the field name: Item1, Item2 ..., that is, "naming" is just a semantic name.

3. What is deconstruction?

Deconstruction, by definition, is the decomposition of the whole into parts.

4. Deconstruct the tuple as follows:

1   var (one, both) = Gettuple (); 2   3   WriteLine ($ "first:{one}, Second:{two}");
1   static (int, int) gettuple () 2   {3       return (1, 2); 4   }

Rationale: Deconstructing a tuple is the assignment of a field value in a tuple to a declared local variable (can be viewed after compilation).

Note: The data type of the variable can be extracted on the left side of the "=" at deconstruction (as shown above), the type of the field in the tuple can be extracted as an implicit type, but the field type in the tuple

Only implicit types can be extracted if they are not identical.

5. Deconstruction can be applied to any type of. Net, but you need to write a deconstruct method member (instance or extension). As shown below:

1 Public   class Student 2   {3 publicly       Student (string name, int age) 4       {5           name = name; 6 Age           = age; 7       } 8    9 public       string Name {get; set;} Ten public int: Age       {get; set;} Public       Void-deconstruct (out string name, out int-age),       {+           = name;16 Age           = Age;17
   }18   }

Use the following methods:

1   var (Name, age) = new Student ("Mike", 2   3   WriteLine ($ "name:{name}, Age:{age}");

Principle parsing: After compiling, the deconstruct method is called by its instance, and then the local variable is assigned a value.

Deconstruct method Signature:

1   //Instance signature 2 public   void deconstruct (out type variable1, out type variable2 ...) 3   4   //Extended signature 5 public   static void deconstruct (this type instance, out type variable1, out type variable2 ...)

Summary: 1. The principle of tuples is that it takes advantage of the nesting of member types or recursion of member types. 2. The compiler is bull B to provide such graceful syntax.

  Use ValueTuple to import: Install-package system.valuetuple
3. Pattern matching (pattern matching)

1. Is expression (is expressions), such as:

1   static int getsum (ienumerable<object> values) 2   {3       var sum = 0; 4       if (values = = null) return sum; 5    6       foreach (var item in values) 7       {8           if (item was short)     //C # 7 before is expressions 9           {Ten               S Um + = (short) item;11           }12           Else if (item is int val)  //C # 7 is expressions13           {               sum + = val;15
   }16           Else if (item is string str && int. TryParse (str, out var result)  //Is expressions and out variables combined with               + + + + + result;19           }20
   
    else if (item is ienumerable<object> sublist)           {               sum + = Getsum (sublist);           }24       }25       return sum;27   }
   

How to use:

1   Conditional control statement (obj is type variable) 2   {3      //processing ... 4   }

Principle Analysis: This is non-is, this extension is actually a combination of AS and if. That is, it first performs an as conversion and then performs an if judgment to determine whether the result is null, not equal to NULL.

Statement block logic, not vice versa. In fact, C # 7 before we can achieve similar functions, but the wording is more cumbersome.

2. Switch statement update (switch statement updates), such as:

1   static int getsum (ienumerable<object> values) 2   {3       var sum = 0; 4       if (values = = null) return 0; 5    6       foreach (var item in values) 7       {8           switch (item) 9           {Ten case               0:                //constant pattern match one                   break;12 Case Short               Sval:       //Type mode matches                   sum = sval;14                   break;15 case               int ival:16                   sum + = ival;17                   break;18 case               string str when int. TryParse (str, out var result):   //Type pattern match + conditional expression sum +                   = result;20                   break;21 case               ienumerable< Object> sublist when Sublist.any ():                   sum + + getsum (sublist);                   break;24               default:25                   throw new InvalidOperationException ("unknown type");           }27       }28       return sum;30   }

How to use:

1   switch (item) 2   {3 case       type Variable1:4           //processing ... 5 Break           , 6 case       type variable2 when Predicate:7           //processing ... 8 break           ; 9       default:10           //processing ...           break;12   }

Rationale: This switch is not a switch, and after compiling you will find that the extended switch is the combination of the AS, if, and goto statements. Like the is expressions, we used to

Now just the wording is cumbersome and not very readable.

Summary: The pattern-matching syntax is to allow us to implement a dynamic call that is similar to polymorphism in a simple case, that is, determining the member type at run time and invoking a specific implementation.

4. Local references and references returned (REF locals and returns)

We know that the ref and out keywords in C # are a complement to value passing to prevent large objects of value types from losing more performance during the copy process. Now in C # 7, the REF keyword has to be

To strengthen, it can not only get a reference to a value type, but also get a local reference to a variable (reference type). Such as:

1   static ref int getlocalref (int[,] arr, func<int, bool> Func) 2   {3 for       (int i = 0; i < arr. GetLength (0); i++) 4       {5 for           (int j = 0; J < arr. GetLength (1); J + +) 6           {7               if (func (Arr[i, J])) 8               {9                   return ref arr[i, j];10               }11           }12       }13       throw new InvalidOperationException ("not Found");   

Call:

1   int[,] arr = {{Ten}, {3},};2   ref var num = ref Getlocalref (arr, c = = = = 600);   ; 4   5   Console.WriteLine (arr[1, 0]);

Print results:

How to use:

1. The return value of the method must be a reference to return:

A) Declaring a method signature must precede the return type with a ref decoration.

b) also add a ref modifier after each return keyword to indicate that it is a return reference.

2. Assign a reference (that is, an assignment), you must precede the declaration of the local variable with a ref decoration, and a ref adornment before the method returns the reference.

Note: C # is developing managed code, so it is generally not desirable for programmers to manipulate pointers. And by the above-mentioned in the use of the process requires a lot of use of ref to indicate that this is a reference variable (after compiling its

Not so much), of course, this is also to improve the readability of the code.

Summary: Although local references and references are returned in C # 7, there are many constraints to prevent abuse, such as:

1. You cannot assign a value to a ref variable, such as:

1   ref int num = ten;   Error: Cannot initialize by reference variable with value

2. You cannot return a variable reference with a lifetime that does not exceed the method scope, such as:

1 Public ref int getlocalref (int num) = ref num;   Error: cannot return parameter by reference because it is not a ref or out parameter

3. Ref cannot decorate "properties" and "indexers".

1   var list = new list<int> (); 2   ref var n = ref list. Count;  

Rationale: Very simple is pointer passing, and personally feel that the use of this syntax is very limited, are used to deal with large objects, the purpose is to reduce the GC to improve performance.

5 function (local functions)

One of the features in C # 7, "Local functions," is as follows:

1    static ienumerable<char> getcharlist (String str) 2    {3        if (Isnullorwhitespace (str)) 4            Throw New ArgumentNullException (nameof (str)); 5     6        return GetList (), 7     8        ienumerable<char> GetList () 9        {Ten for            (int i = 0; i < str. Length; i++)            {                yield return str[i];13            }14        }15    }

How to use:

1   [data type, void] Method name ([parameter]) 2   {3      //method body;[] All are optional 4   }

Principle Analysis: Although the local function is declared inside other functions, it is compiled as a static function modified by internal, it belongs to the class, as to why it can use the parent letter

What about the local variables and parameters in the number? That's because the compiler generates a new type (CLASS/STRUCT) based on the members it uses and then passes it into the function. From the above, the sound of the local function

It is independent of position and can be nested indefinitely.

Summary: The individual feels that the local function is a semantic complement to the C # exception mechanism (as in the above example), and the syntax that is set for the code to provide a clear structure. But local functions also have their drawbacks,

Is that the code in the local function is not reusable (except for reflection).

6. More expression bodies (more expression-bodied members)

In C # 6, expression body members were supported, but only function members and read-only properties were supported, and this feature was extended in C # 7 to support more members: constructors

, destructors, properties with Get,set accessors, and indexers. As shown below:

1 Public   class Student 2   {3       private string _name; 4    5       //expression-bodied Constructor 6       public Student (string name) = = _name = name; 7    8       //expression-bodied Finalizer 9       ~student () = Console.WriteLine ("finalized!");       //expression-bodied get/set accessors.12 public       string Name13 {+           get = _name;15< C14/>set = _name = value?? "Mike";       }17       //expression-bodied indexers19 public       string this[string name] = Convert.tobase64string (Encoding.UTF8.GetBytes (name));   

Note: Indexers are actually supported in C # 6, but the other three are not supported in C # 6.

7. Throw expression (throw expressions)

The exception mechanism is an important part of C #, but not all statements can throw exceptions before, such as: Conditional expressions (?). :), NULL merge operator (??). ), some lambda

An expression. With C # 7, you can throw exceptions anywhere. Such as:

1 Public   class Student 2   {3       private string _name = GetName ()?? throw new ArgumentNullException (Nameof (Getnam e)); 4    5       private int _age; 6    7 public       int age 8       {9           get = _age;10           set = _age = Value <= 0 | | Value >= 130? throw new ArgumentException ("argument not valid"): value;11       }12       static string GetName () = null;14   }
8. Extended asynchronous return type (generalized async return types)

The previously asynchronous return type must be: Task, task<t>, void, and now a new type in C # 7: Valuetask<t>, as follows:

1 public   Async valuetask<int> Func () 2   {3       await task.delay (+); 4       return 100;5   }

Summary:valuetask<t> and ValueTuple very similar, so do not enumerate: valuetask<t> and Task between the similarities and differences, but they are to optimize the specific scene performance and

The new type.

  Use valuetask<t> to import: Install-package System.Threading.Tasks.Extensions
9. Improvement of digital text syntax (Numeric literal syntax improvements)

C # 7 also contains two new features: binary literals, numeric separators, as follows:

1   var one = 0b0001;2   var sixteen = 0b0001_0000;3   4   Long salary = 1000_000_000;5   decimal pi = 3.141_592 _653_589m;

Note: Binary text starts with 0b (0 b), the letters are not case-sensitive, and the number separators are only three places that cannot be written: the beginning, the end, and the decimal point.

Summary: Binary text, a numeric delimiter, makes the constant value more readable.

The rainy night Xiaoxiang QQ Group:297829948 Original: 30 minutes Master c#7 Source:http://www.cnblogs.com/VVStudy/p/6551300.html This article is copyrighted by the author and the blog Park, Welcome to reprint, but without the consent of the author must retain this paragraph, and in the article page obvious location to the original link.

Detailed c#7.0 new features

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.