Dry goods are coming! C# 7.0 new features (vs2017 available)

Time:2022-1-9

preface

Microsoft released a new vs 2017 yesterday There are many, many things that follow Net new version ASP Net new version wait.. Too much Really not digested

Share the new features of c#7.0 that were announced in December 2016. Although they came out very early, our ide does not support them

However, in yesterday’s vs2017, it is perfect and can be used

E Wen OK, step by step official introduction address: https://docs.microsoft.com/zh-cn/dotnet/articles/csharp/csharp-7

List it firstRelated syntax:

1. Out variables

2. Tuples (tuples)

3. Pattern matching

4. Ref locales and returns

5. Local functions

6. More expression bound members

7. Throw expressions

8. Generalized async return types

9. Numeric literal syntax improvements

text

1. Out variables

In the past, when we used the out variable, we need to declare it externally before we can pass in the method, similar to the following:

string ddd = ""; // Declare variables first
ccc.StringOut(out ddd);
Console.WriteLine(ddd);

In c#7.0, we can directly declare the parameter while passing it without declaration, as follows:

StringOut(out string ddd); // Simultaneous declaration of transmission
Console.WriteLine(ddd);
Console.ReadLine();

2. Tuples (tuples)

Once upon a time NET4. 0, Microsoft gave us a solution called tuple for multiple return values. Similar codes are as follows:


static void Main(string[] args)
 {
 var data = GetFullName();
 Console.WriteLine(data.Item1);
 Console.WriteLine(data.Item2);
 Console.WriteLine(data.Item3);
 Console.ReadLine();
}
static Tuple<string, string, string> GetFullName() 
{
 return new Tuple<string, string, string>("a", "b", "c");
}

The above code shows a method that returns tuples containing three strings. However, when we get the value and use it, our heart has exploded. What the hell are Item1, Item2 and Item3? Although they meet our requirements, they are really not elegant

So, in c#7.0, Microsoft provides a more elegant solution: (Note: system. Valuetuple needs to be referenced through nuget)As follows:

static void Main(string[] args)
 {
 var data=GetFullName();
 Console. WriteLine(data.a); // Get values using naming
 Console.WriteLine(data.b);
 Console.WriteLine(data.c);
 Console.ReadLine();

 }


 //Method is defined as multiple return values and named
 private static (string a,string b,string c) GetFullName()
 {
 return ("a","b","c");
 }

Deconstructing tuples, sometimes we don’t want to use VaR anonymity to get them, so how to get ABC? We can:

static void Main(string[] args)
 {
 //Define deconstruction tuple
 (string a, string b, string c) = GetFullName();

 Console.WriteLine(a);
 Console.WriteLine(b);
 Console.WriteLine(c);
 Console.ReadLine();

 }


 private static (string a,string b,string c) GetFullName()
 {
 return ("a","b","c");
 }

3. Pattern matching
In c#7.0, the game of matching pattern is introduced. Take an old chestnut first For an object type, we want to judge whether it is int. if it is int, we will add 10 and then output it. We need the following:

object a = 1;
If (a is int) // is judgment
{
 int b = (int)a; // Dismantle
 int d = b+10; // Plus 10
 Console. WriteLine(d); // output
}

In c#7.0, the first is a small extension of is. We just need to write it like this, as follows:

object a = 1;
If (a is int c) // here, after it is judged as int, it is directly assigned to C
{
 int d = c + 10;
 Console.WriteLine(d);
}

Is that convenient? Especially comrades who often use reflection

So the question is, which is the best excavator technology?! (cough, Pooh, kidding)

Actually, what if there are multiple types to match? Multiple if else? Of course, no problem, but Microsoft dad also providedNew ways of playing switch, let’s take a look, as follows:

We define an add method that takes object as a parameter and returns a dynamic type


 static dynamic Add(object a)
 {
 dynamic data;
 switch (a)
 {
 case int b:
  data=b++;
  break;
 case string c:
  data= c + "aaa";
  break;
 default:
  data = null;
  break;
 }
 return data;
 }

Run the following to pass in the int type:


object a = 1;
var data= Add(a);
Console.WriteLine(data.GetType());
Console.WriteLine(data);

The output is shown in the figure:

We pass in parameters of string type. The code and output are as follows:


object a = "bbbb";
var data= Add(a);
Console.WriteLine(data.GetType());
Console.WriteLine(data);

Through the above code, we can realize how smooth and powerful the new play method of switch is

Case when filtering of matching patterns

Some gay friends will ask Now that we can match the types in the switch, can we filter the values by the way? The answer is certainly yes

Let’s change the switch code above as follows:


 switch (a)
 {
 case int b when b < 0:
  data = b + 100;
  break;
 case int b:
  data=b++;
  break;
 case string c:
  data= c + "aaa";
  break;
 default:
  data = null;
  break;
 }

Try passing in – 1. The results are as follows:

4. Ref locales and returns

It has been supplemented, please move to:Ref locales and returns of C # 7.0

5. Local functions

Well, this is a little subversive As we all know, local variables refer to variables that can be accessed only in specific procedures or functions.

This local function, as its name implies, is a function that can only be accessed in a specific function

The method of use is as follows:

public static void DoSomeing()
 {
 //Call dosmeing2
 int data = Dosmeing2(100, 200);
 Console.WriteLine(data);
 //Define local functions, dosmeing2
 int Dosmeing2(int a, int b)
 {
 return a + b;
 }
 }

Er, the explanation is that a dosomeing2 method is defined in dosomeing It was called before

(Note:It is worth mentioning that local functions defined anywhere in the method can be called in the method without line by line parsing)

6. More expression bound members

In c#6.0, it is provided that the method body with only one statement can be abbreviated into an expression.

As follows:

public void CreateCaCheContext() => new CaCheContext();
 //Equivalent to the following code
 public void CreateCaCheContext()
 {
 new CaCheContext();
 }

However, C #7.0 does not support constructors, destructors, and property accessors The code is as follows:

//Expression writing of constructor
public CaCheContext(string label) => this.Label = label;

//Expression writing of destructor
~CaCheContext() => Console.Error.WriteLine("Finalized!");

private string label;

//Expression writing of get / set property accessor
public string Label
{
 get => label;
 set => this.label = value ?? "Default label";
}

7. Throw expressions

Before c#7.0, we wanted to judge whether a string was null. If it was null, we threw out the exception. We need to write this:

public string IsNull()
 {
 string a = null;
 if (a == null)
 {
 Throw new exception ("exception!");
 }
 return a;
 }

In this way, it is very inconvenient for us, especially in ternary expressions or non empty expressions. We can’t get rid of this exception. We need to write an IF statement

In c#7.0, we can:

public string IsNull()
 {
 string a = null;
 return a ??  Throw new exception ("exception!");
 }

 8. Generalized async return types

Well, how to put it, in fact, I don’t use asynchronous, so I don’t have a deep understanding of this feeling. I still think it should be useful in some specific situations

I will directly translate the official original text, and the example code is also the official original text

The asynchronous method must return void, task or task < T >, and a new valuetask < T > is added this time to prevent the result of asynchronous operation from allocating task < T > when it is available while waiting. For asynchronous scenarios where buffering is designed in many examples, this can greatly reduce the number of allocations and significantly improve performance.

The main meaning of the official example is that when a data has been cached, valuetask can be used to return asynchronous or synchronous solutions


 public class CaCheContext
 {
 public ValueTask<int> CachedFunc()
 {
 return (cache) ? new ValueTask<int>(cacheResult) : new ValueTask<int>(loadCache());
 }
 private bool cache = false;
 private int cacheResult;
 private async Task<int> loadCache()
 {
 // simulate async work:
 await Task.Delay(5000);
 cache = true;
 cacheResult = 100;
 return cacheResult;
 }
 }

The code and result of the call are as follows:

//The main method cannot be modified with async, so a delegate is used
 static void Main(string[] args)
 {
 Action act = async () =>
 {
 CaCheContext cc = new CaCheContext();
 int data = await cc.CachedFunc();
 Console.WriteLine(data);
 int data2 = await cc.CachedFunc();
 Console.WriteLine(data2);
 };
 //Call delegate 
 act();
 Console.Read();

 }

We called the above code twice in a row. For the first time, we waited for 5 seconds and the result appeared The second time did not wait for direct appearance, and the result was consistent with the expected effect

 9. Numeric literal syntax improvements

This is pure To look good

In c#7.0, “” is allowed in numbers This division symbol To improve readability, for example:

int a = 123_456;
 int b = 0xAB_CD_EF;
 int c = 123456;
 int d = 0xABCDEF;
 Console.WriteLine(a==c);
 Console.WriteLine(b==d);
 //The above code will display two trues, with "" in the number Delimiters do not affect the results, just to improve readability

Of course, since it is a number type separator, decimal, float and double} can be separated in this way.

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support developpaer.