C# Basic Supplements Series II: New Function Points in C# 7.0

 

first part:

C# is a general-purpose, type-safe, object-oriented programming language. Has the following characteristics:

(1) Object-oriented: C# is a rich implementation of the object-oriented paradigm, which includes encapsulation, inheritance, and polymorphism. C# object-oriented behaviors include:

  • Unified Type System
  • Classes and Interfaces
  • properties, methods, events

(2) Type safety: C # also allows dynamically specifying types through the dynamic keyword. However, C # is still a predominantly statically typed language. It is a strongly typed language because its type rules are very strict, for example, you cannot call a function that interprets an int with an argument of type float unless you explicitly convert the float to int, This helps prevent coding errors.

(3) Memory management: C# relies on automatic memory management at runtime. Its common language runtime library has a garbage collector, which reclaims the space occupied by objects that are no longer referenced at appropriate non-time, which frees the programmer to manually release object's memory. C# doesn't eliminate pointers, it just makes pointers unnecessary for most programming tasks. For performance-critical applications, pointers can still be used, but only in blocks of code that are explicitly marked as unsafe.

(4) C# and CLR: C# relies on the memory management and exception handling provided by runtime . CLR allows developers to build applications in different languages. C # is one of several managed languages ​​that are compiled into managed code. Managed code is expressed in Intermediate Language or IL . The CLR converts IL to the machine's native code, such as X86 or X64 , which is usually executed just before that, which is called Just-In-Time ( JIT ) compilation. Ahead-time compilation can also be used to improve startup times for large assemblies, or on resource-constrained devices. The presence of metadata allows assemblies to reference types in other assemblies without additional files.

(5) Relationship between CRL and .Net Framework

.NET Framework consists of CLR and a large number of libraries; the class library includes the core class library (that is, the basic class library BCL) and the application class library, and the application class library depends on the core class library

 

Mother-in-law and mother have said so much, I believe everyone knows that, well, let's see what makes you applaud in C# 7.0 through the code.

Part 2: What's New in C# 7.0

(1) Improvement of digital literals:

Number literals in C# 7 can contain underscores to improve readability, these are called number separators and are ignored by the compiler.

code show as below:

operation result:

Note: Binary literals can be specified with a 0b prefix.

So don't be surprised to see this way of writing, just to improve readability.

(2) Out variables and discards (receive out variables and discard out variables)

Code:

Previously we wrote:

 

Now in C# 7.0 you can write:

We don't need to define variables to receive values ​​outside, but write them directly inside. Is the code more concise? Another interesting point is that when a method needs to return multiple values, we can use out _ , to selectively receive the returned value. In the code in the above figure, the method SomeBigMethod returns four values, but when we receive the returned value, we can use out _ not to receive the returned value, but to use out int x, to receive the returned value, is it very flexible.

The result of running the code is as follows:

ILSpy result:

// Methods
    .method private hidebysig static 
        void Main (
            string[] args
        ) cil managed
    {
        // Method begins at RVA 0x2050
        // Code size 49 (0x31)
        .maxstack 4
        .entrypoint
        .locals init (
            [ 0 ] int32,
            [1] bool,
            [ 2 ] int32,
            [ 3 ] int32,
            [ 4 ] int32,
            [ 5 ] int32
        )

        // (no C# code)
        IL_0000: nop
        // bool successful = int.TryParse("123", out result);
        IL_0001: ldstr "123"
        IL_0006: ldloca.s 0
        IL_0008: call bool [System.Runtime]System.Int32::TryParse(string, int32&)
        IL_000d: stock. 1 
        // SomeBigMethod(out int _, out int _, out int x, out int _); 
        IL_000e: ldloca.s 3 
        IL_0010: ldloca.s 4 
        IL_0012: ldloca.s 2 
        IL_0014: ldloca.s 5
        IL_0016: call void ConsoleApp1.Program :: SomeBigMethod (int32 &, int32 &, int32 &, int32 &)
        // (no C# code)
        IL_001b: nop
        // Console.WriteLine(x);
        IL_001c: ldloc.2
        IL_001d: call void [System.Console]System.Console::WriteLine(int32)
        // (no C# code)
        IL_0022: nop
        // Console.WriteLine(result);
        IL_0023: ldloc.0
        IL_0024: call void [System.Console]System.Console::WriteLine(int32)
        // (no C# code)
        IL_0029: nop
        // Console.ReadKey();
        IL_002a: call valuetype [System.Console]System.ConsoleKeyInfo [System.Console]System.Console::ReadKey()
        IL_002f: pop
        // (no C# code) 
        IL_0030: ret
    } // end of method Program::Main

(3)Patterns

What it does: You can use the is operator to introduce a variable, which is called a pattern variable. I don't understand, just look at an example to understand.

code show as below:

Analysis: x is string The function of s is: if x can be converted to string and the converted value is assigned to s, the output result is the length of the string.

The switch statement also supports this mode, and you can also use the when clause to specify conditions, the code is as follows:

 operation result:

Analysis: Foo2(9) passes 9, which is of type int, so it enters the first case clause, so the final output result is: It is an int!, this explanation gives zero points, let's pass ILSpy to see what this syntactic sugar is, as shown in the following figure:

I won't explain it, everyone will understand at a glance, whether you want to take a picture of your thigh, TM turns out to be that simple! ! !

(4) Local methods

Role: A local method is a method declared inside another function. Here I give it in English, because it is the most accurate way to give it, and TM can't understand it when it is translated from Chinese.

operation result:

Analysis:   A local method is defined, the return value type is int, the incoming parameter is value, and the return value is: value*value*value+i

Cube(2), call the incoming value 2, so the final calculated value is 2*2*2+9=17

Note: A native method is only visible to the containing function, and the variable containing the native method can be used.

The result of ILSpy decompilation:

It can be seen that when Cube(2) is called, it is finally compiled into a method such as Cube(2,ref xx), but the internal implementation of the <WriteCubes>g__Cube|3_0 method cannot be seen.

(5) C# 6 introduces the "fat-arrow" syntax of methods, which can be used in read-only, properties, operators and indexers. c# 7 extends this to constructors, read/write properties, finalizers

Code:

ILSPy code result:

 (6) For c# 7, probably the most significant improvement is explicit tuple support

What it does: Tuples provide an easy way to store a set of related values

Code:

operation result:

Analysis: var bob = ("Bob", 23); defines a tuple, you can use bob.Item1 to access the first parameter, you can use bob.Item2 to access the second parameter, but the question is, why is this possible to visit? ? ?

ILSpy result:

As you can see, the tuple is actually a generic type of ValueTuple<,>, where string int is determined by the type of your value, so why can you use Item1 and Item2 to access the corresponding value?

 

First of all, Item1 and Item2 are defined in ValueTuple<T1, T2>, so why I access Item1 is "Bob", that is because "Bob" is assigned to Item1 in the constructor, so I understand.

In addition, it can be seen that a tuple is a structure and belongs to a value type. I'm not done with tuples here, thanks to the magic of the compiler, tuple elements can be named something like this:

ILSpy result:

With the help of tuples, functions can return multiple parameters without resorting to out parameters:

operation result:

ILSpy result:

Note: Tuples implicitly support anti-parsing patterns, so they can be easily decomposed into individual variables. We can rewrite the previous main method so that the tuple returned by GetFilePosition is assigned to two local variables: row and cloum:

 

operation result:

ILSPy result: (result same as above)

Okay, enough about tuples, let's see how to throw exceptions.

(7) Throwing an exception

Feature: Prior to C# 7, throw was always declared, now it can appear as an expression in a function body, and it can also appear in ternary expressions.

 ILSpy result:

(8) String interpolation

Go directly to the code:

If you want to display multiple lines, you can write:

Note: The $ sign must be before the @ sign.

ILSpy result:

I won't say more about it, just continue with the following knowledge points.

(9) Exception filters

What it does: Allows you to apply a condition to the catch.

(10) Reference local variables Ref Locals

What it does: A very important point was introduced in C# 7.0, whereby you can define a local variable that refers to an element in an array or a field in an object.

Code:

Note: Ref Locals must be an element, field, or local variable in an array, not a property. It is usually used with ref returns.

 

operation result:

Analysis: ref int age When this variable is marked, it is a variable of reference type.

(11)Ref Returns

 Role: You can return a ref local in a method, this way is called ref return

Code:

operation result:

Analysis: private static ref int GetX() is actually a method that returns a value of int32& (that is, an INT32 type marked with a memory pointer), that is, returns an address, so that after I modify the value, it is actually the modified value of x.

ILSpy result:

Note: ldsflda int32: It pushes the address of a static field x into the stack, ret, and then returns. In the Main method, after calling the above method, the value is taken out from the top of the stack and stored in the local variable list index inside position 0.

Then take the value whose index position is 0 in the local variable, and push it into the stack. Note that the key point is that stind.i4 stores the address of the value of ldc.i4.s 9, which changes the value of x. So this int32& is actually the address of a variable, which is what we usually call a pointer.

 

Well, basically, the new functions of C# 7.0 are almost the same. I will continue to add new knowledge points of C# 7.0 in the future, I hope it will help you! thanks.

Finally, everyone is welcome to join my C#+.Net Core English book translation group. I will update the translated English materials through the blog from time to time, hoping to get the latest C# knowledge and improve you and me at the same time.

 

Reference book: "C 7.0 in a Nutshell 7th Edition"

 

Author: Guo Zheng

Source: http://www.cnblogs.com/runningsmallguo/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325088804&siteId=291194637