Explore C #6.0 syntactic sugar analysis,
Reading directory:
Automatic attribute initialization by default
Usage:
public string Name { get; set; } = "hello world";
To make it easy to understand and use the 2.0 syntax, the compiler generates the following code:
public class Customer { [CompilerGenerated] private string kBackingField = "hello world"; public Customer() { this.kBackingField = "hello world"; }public string Name{ [CompilerGenerated] get { return this.<Name>k__BackingField; } [CompilerGenerated] set { this.<Name>k__BackingField = value; }}}
From the generated code, we can see that the compiler initializes the attribute information during the instance constructor.
Automatic read-only attribute is initialized by default.
Usage:
public string Name1 { get; } = "hello world";
The code generated by the compiler is as follows:
[CompilerGenerated] private readonly string kBackingField; public Customer() { this.kBackingField = "hello world"; } public string Name1 { [CompilerGenerated] get { return this.k__BackingField; } }
The default initialization value is actually assigned to the constructor, so it has nothing to do with attribute read-only.
Functions Whose expressions are subject
Usage:
Body Get(int x, int y) => new Body(1 + x, 2 + y);
The compiler generates the following:
private Program.Body Get(int x, int y){ return new Program.Body(1 + x, 2 + y);}
This simplifies the compilation of single-line methods, saving you the effort to write braces.
It also supports writing without return values:
void OutPut(int x, int y) => Console.WriteLine("hello world");
Asynchronous function writing is also supported:
async void OutPut(int x, int y) => await new Task(() => Console.WriteLine("hello wolrd"));The expression is the attribute of the subject (Value assignment)
Usage:
public string Name2 => "hello world";
The code generated by the compiler is as follows:
public string Name2 { get { return "mushroomsir"; } }
The compiler only generates read-only attributes.
Static class Import
This feature allows you to import all static members of a certain type at a time, so that static members can be directly used in subsequent code without type restrictions, just like using the static method below this type.
using static System.Console; class Program
{ static void Main(string[] args) { WriteLine("hello wolrd"); }}
The code generated by the compiler is as follows:
private static void Main(string[] args) { Console.WriteLine("hello wolrd"); }
Saves the need for repeated Writing of type names.
Null condition Operator
Usage:
Customer customer = new Customer();
string name3 = customer?.Name;
Equivalent:
Customer customer = new Customer();if (customer1 != null){ string name = customer1.Name;}
Yes ?? Combined use:
if (customer?.Face2()??false)
It can also be used together with two:
int? Length = customer?.Name?.Length;
You can also call the following methods:
customer?.Face();
This syntactic sugarThe purpose is to check whether it is null before use.If the returned value is null, the variable is null. Therefore, you need an int type that can be null, that is, int ?.
String formatting
String. Format is inconvenient: You must enter "String. Format", use the {0} placeholder, and Format it in sequence. This is prone to errors.
var s = String.Format("{0} is {1} year {{s}} old", p.Name, p.Age);
The new syntax sugar is easier to use:
var s = $"{p.Name} is {p.Age} year{{s}} old";
The compiler generates the following code, which is no different from the previous one:
var s = String.Format("{0} is {1} year{{s}} old", p.Name, p.Age);
Interestingly, the new formatting method also supports direct assignment of any expressions:
var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";Index Initialization
Usage:
var numbers = new List { [7] = "seven", [9] = "nine", [13] = "thirteen" };
The code generated by the compiler is as follows:
List list = new List(); list[7] = "seven"; list[9] = "nine"; list[13] = "thirteen";
Exception filter when
Usage:
try { throw new ArgumentException("string error"); } catch (ArgumentException e) when (myfilter(e)) { Console.WriteLine(e.Message); }static bool myfilter(ArgumentException e) { return false; }
This syntax sugar is used to verify the bool returned by the myfilter method in the when brackets before entering the catch. If the return value is true, the system directly throws an exception if the false parameter does not go through the catch function.
Using this filter can better judge whether an error is processed or thrown again. According to the previous practice, if the catch Block needs to be throttled again, it needs to throw again. The error source is discarded after being eaten, instead of the original one. With the when syntax
Sugar, you can directly locate the error source.
Await in catch and finally code blocks
Await asynchronous processing was proposed in c #5.0, but cannot be used in catch and finally code blocks. This C #6.0 update is supported.
Usage:
async void Solve() { try { await HttpMethodAsync(); } catch (ArgumentException e) { await HttpMethodAsync(); } finally { await HttpMethodAsync(); } }
The compiler generates catch and finally await into MoveNext () in the state machine. It turns out that there are only TaskAwaiter, and now there are two more. The code in the state machine is the same as the original code, but it is more complicated. If you are interested, you can look at Async and Await for further analysis.
Nameof expression
Usage:
string name = "";Console.WriteLine(nameof(name));
The console outputs "name ".
Sometimes you need the string names of some Members in the program. For example, if you want to know the ArgumentNullException type string name when an ArgumentNullException exception is thrown, you can use nameof to obtain the characters.
String "ArgumentNullException ". The current practice is to manually copy it, but it is easy to forget to change the string when restructuring the name, so you can avoid using nameof.
When the following code is used, the compiler only obtains the last ZipCode.
nameof(person.Address.ZipCode)
The compiler generates the following code:
Console.WriteLine("name");Extension Method
Using static System. linq. enumerable; // introduce the type, instead of the namespace class Program {static void Main () {var range = Range (5, 17); // OK: not an extension method var odd = Where (range, I => I % 2 = 1); // Error, not in the global scope var even = range. where (I => I % 2 = 0); // OK }}
First, Enumerable is a static class, which contains various extension methods, such as range. Static is used to import static members of the type at one time. Although rang is a static method, it cannot be imported, such as where.
Because the extension method is applied to instance members (the first this instance parameter of the extension method), it cannot directly apply the scope to the global, so var odd = Where (range, I => I % 2 = 1) is incorrect.
But static can import the type extension method as the role function of the extension method itself, so var even = range. Where (I => I % 2 = 0) is OK.
Here, it may be a little bit difficult. lz should be clear as much as possible. The new static usage has two functions:
Summary
I saw some articles introduced in the garden. I was interested for a moment. I installed a Community edition after work to study and share it. Although Microsoft has been developing new things, they are all from bottom to top iterations, so learning is very fast.
Reference https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6#expression-bodied-function-members