C x 9.0 is finally coming. Are you still learning? Take VS and read it together! (it should be the first article of the whole network)

Keywords: Lambda SDK Programming github

1: Background

1. Story telling

Good news,. NET 5.0 finally released the fifth preview version on June 10, 2020. The sharp eyed students must have seen that in this version, C ා 9.0 is finally supported. Applause here, great!!!

. Net5 official link

It can be seen that the current C ා 9 is still a preview version, which implements some new languages for developers to taste in advance. From the roslyn warehouse of github, it can be seen that 17 new features are ready to be implemented at present, and 8 of them have been implemented at this stage, of which In Progress indicates that they are under development.

Preview of new features

2. Necessary for installation

Find your own version type of vs...

2: Research on new characteristics

1. Target-typed new

This name must be left to the great master who studies the book of changes. I dare not make mistakes if I haven't seen the world. I won't make a bad impact on the fortune. The so-called "delivering gold into iron" means that the iron from time to time is like gold. But the general meaning is to directly new the types of local variables you define. The words summarized in issues are:

Summary: Allow Point p = new (x, y);
Shipped in preview in 16.7p1.

Next is the whole code. Look at the specific differences before and after use.

    class Program
        static void Main(string[] args)
            //Old grammar
            var person = new Person("mary", "123456");

            //New grammar
            Person person2 = new("mary", "123456");


    public class Person
        private string username;
        private string password;

        public Person(string username, string password)
            this.username = username;
            this.password = password;

        public override string ToString()
            return $"username={username},password={password} \n";

Then use ilspy to see if the following il code omits Person and makes you feel more secure.

Generally speaking, this grammar is OK. It can prolong the service life of the keyboard.

2. Lambda discard parameters

Literally, it means that you can use the cancel parameter on the lambda. It sounds strange. What's the original meaning? Sometimes the parameters of anonymous method signature on lambda are unnecessary, but the definition must be verified before, which will pollute the method body, that is, it can be accessed in the body, as shown in the following figure:

But sometimes, because of objective reasons, you have to use a delegation like func < int, int, int > and you don't want the parameters of method signature to pollute the method body. I guess there is such a scenario in functional programming, which may be a little similar to the EmptyResult effect in MVC.

Well, I think you probably know what it means. Next, practice...

    Func<int, int, int> func = (_, _) =>
        return 0;

    var result = func(10, 20);

As you can see from the figure, I can't find the so-called_ Variable, this is amazing, how to do it? Take this curiosity to see what its IL code looks like.

.method private hidebysig static 
	void Main (
		string[] args
	) cil managed 
	// Method begins at RVA 0x2048
	// Code size 45 (0x2d)
	.maxstack 3
	.locals init (
		[0] class [System.Runtime]System.Func`3<int32, int32, int32> func,
		[1] int32 result

	IL_0000: nop
	IL_0001: ldsfld class [System.Runtime]System.Func`3<int32, int32, int32> ConsoleApp1.Program/'<>c'::'<>9__0_0'
	IL_0006: dup
	IL_0007: brtrue.s IL_0020

	IL_0009: pop
	IL_000a: ldsfld class ConsoleApp1.Program/'<>c' ConsoleApp1.Program/'<>c'::'<>9'
	IL_000f: ldftn instance int32 ConsoleApp1.Program/'<>c'::'<Main>b__0_0'(int32, int32)
	IL_0015: newobj instance void class [System.Runtime]System.Func`3<int32, int32, int32>::.ctor(object, native int)
	IL_001a: dup
	IL_001b: stsfld class [System.Runtime]System.Func`3<int32, int32, int32> ConsoleApp1.Program/'<>c'::'<>9__0_0'

	IL_0020: stloc.0
	IL_0021: ldloc.0
	IL_0022: ldc.i4.s 10
	IL_0024: ldc.i4.s 20
	IL_0026: callvirt instance !2 class [System.Runtime]System.Func`3<int32, int32, int32>::Invoke(!0, !1)
	IL_002b: stloc.1
	IL_002c: ret
} // end of method Program::Main

From the above IL code, the anonymous method becomes the < main > b of the < > C class__ 0_ 0 method, full signature: consoleapp1. Program / '< C': '< main > b__ 0_ 0 '(int32, int32), then look for < main > b__ 0_ Definition of the 0 method.

.class nested private auto ansi sealed serializable beforefieldinit '<>c'
	extends [System.Runtime]System.Object
	.method assembly hidebysig 
		instance int32 '<Main>b__0_0' (
			int32 _,
			int32 _
		) cil managed 
		// Method begins at RVA 0x2100
		// Code size 7 (0x7)
		.maxstack 1
		.locals init (
			[0] int32

		IL_0000: nop
		IL_0001: ldc.i4.0
		IL_0002: stloc.0
		IL_0003: br.s IL_0005

		IL_0005: ldloc.0
		IL_0006: ret
	} // end of method '<>c'::'<Main>b__0_0'

What does this mean? It shows that the two parameters are real, but the compiler has made a syntactic restriction to prevent you from accessing the so-called "Wu".

wait... There is a problem, how does the method signature in IL look like this: < main > b__ 0_ 0 (int32 _ ,int32 _ ), you should know that duplicate parameter names cannot appear in method signature. For example, the following definition must be wrong.

What does this mean? It shows that this syntax sugar needs not only compiler support, but also the underlying JIT support. How to prove it? Let's use windbg to dig the bottom... For the convenience of debugging, it is modified as follows:

        static void Main(string[] args)
            Func<int, int, int> func = (_, _) =>
                Console.WriteLine("Enter method body!!!");
                return 0;

            var result = func(10, 20);

0:000> !clrstack -p
OS Thread Id: 0x52e8 (0)
0000007035F7E5C0 00007ffaff362655 ConsoleApp1.Program+c.b__0_0(Int32, Int32) [C:\5\ConsoleApp1\ConsoleApp1\Program.cs @ 13]
        this (0x0000007035F7E600) = 0x000001968000cb48
        _ (0x0000007035F7E608) = 0x000000000000000a
        _ (0x0000007035F7E610) = 0x0000000000000014

As you can see from the figure, although they are all_ , but there are two complete stack addresses on the thread stack. 0x0000007035F7E608 and 0x0000007035F7E610.

3: Summary

In general, C is more and more close to functional programming, more and more like Scala, just like the slogan of Jquery: Write less, do more.

OK, let's talk about these two first. Let's install the tools first and continue the dissection tomorrow~~~

If you have more questions to interact with me, please come in under the scan~

Posted by EverToDesign on Fri, 12 Jun 2020 19:55:33 -0700