0新增语法糖,0语法糖剖析

开卷目录:

翻阅目录:

机关属性默许早先化

选用情势:

public string Name { get; set; } = "Hello World";

编写翻译器生成代码:

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;
    }
}
}

从扭转代码中得以看看编写翻译器是在实例化构造函数时,开端化属性音信的。

扩展自动属性语法

机动属性初阶化表明式。

public class Example
{
    // 6.0新增语法糖
    public string FirstName { get; set; } = "Monkey";

    // 6.0之前的写法
    //private string _firstName = "Monkey";
    //public string FirstName
    //{
    //    get { return _firstName; }
    //    set { _firstName = value; }
    //}

    public Example()
    {

    }
}

机关属性能够不定义 set 访问器。

public class Example
{
    public string FirstName { get; } = "Monkey";

    public string LastName { get; }

    public Example()
    {

    }
}

只读属性能够在类型构造函数中早先化。

public class Example
{
    public string FirstName { get; } = "Monkey";

    public string LastName { get; } 

    public Example(string lastName)
    {
        LastName = lastName;
    }
}
  1. 电动属性默许开端化
  2. 活动只读属性私下认可开首化
  3. 表明式为基点的函数
  4. 表明式为主旨的习性(赋值)
  5. 静态类导入
  6. Null条件运算符
  7. 字符串格式化
  8. 0新增语法糖,0语法糖剖析。索引起先化
  9. 特别过滤器when
  10. catch和finally代码块内的Await
  11. nameof表达式
  12. 扩大方法
  13. 总结
  1. 机动属性私下认可开始化
  2. 机关只读属性私下认可开端化
  3. 表明式为主体的函数
  4. 表明式为中央的属性(赋值)
  5. 静态类导入
  6. Null条件运算符
  7. 字符串格式化
  8. 索引开首化
  9. 卓殊过滤器when
  10. catch和finally代码块内的Await
  11. nameof表达式
  12. 美高梅开户网址 ,增加方法
  13. 总结

自动只读属性暗许初始化

动用情势:

public string Name1 {get;} = "hello world";

编写翻译器生成代码:

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;
    }
}
}

从变化的代码中也得以见到编写翻译器是在实例化构造函数时,起先化属性新闻的。

Null 条件运算符

用以在实践成员访问 (?.) 或索引 (?[) 操作在此之前,测试是或不是留存 NULL。
可协理理编辑写更少的代码来拍卖 null 检查。

成员访问 (?.) :

public static string Truncate(string value, int length)
{
    return value?.Substring(0, Math.Min(value.Length, length));

    // C# 6.0 之前的写法
    //string result = value;
    //if (value != null)
    //{
    //    result = value.Substring(0, Math.Min(value.Length, length));
    //}
    //return result;
}

索引 (?[) 操作:

List<Example> examples = null;
Example example = examples?[0]; 
// 上述相当于 Example? item = (examples != null) ? examples[0] : null

Console.WriteLine(example == null); // 输出 True

电动属性暗中认可初阶化

应用方法:

public string Name { get; set; } = "hello world";

为了有利于掌握使用贰.0语法呈现,编写翻译器生成代码如下:

 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;
    }
}
} 

 从变化代码中得以观看编写翻译器是在实例构造函数时,开头化属性新闻的。

自动属性暗中同意开头化

运用情势:

public string Name { get; set; } = "hello world";

为了便于精晓使用2.0语法展现,编写翻译器生成代码如下:

 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;
    }
}
} 

 从转变代码中得以看来编写翻译器是在实例构造函数时,发轫化属性新闻的。

表明式为重点的函数

动用方法:

Body Get(int x, int y) => new Body(1 + x, 2 + y);

编写翻译器生成代码:

private Program.Body Get(int x, int y)
{
      return new Program.Body(1+x, 2+y);
}

从转变的代码中可以看看简化了单选方法的编排,省去写大括号的造诣。
再正是也帮助未有重回值的写法:

void OutPut(int x, int y) => Console.WriteLine("hello, world");

也帮助异步函数的编写制定:

async void OutPut(int x, int y) => await new Task(() => Console.WriteLine("hello world"));

导入静态类 (using static)

允许访问类型的静态成员,而无需限定使用项目名称实行走访:

//静态导入Console
using static System.Console;
using static System.Math;
using static System.DayOfWeek;

class Program
{ 
        static void Main()
        { 
                //直接使用方法而不用Console.WriteLine 
                WriteLine(Sqrt(3*3 + 4*4)); 
                WriteLine(Friday - Monday); 
        }
}

自行只读属性暗中同意开头化

应用办法:

public string Name1 { get; } = "hello world";

编写翻译器生成代码如下:

[CompilerGenerated] 
private readonly string kBackingField; 
public Customer() 
{
 this.kBackingField = "hello world";
 } 
public string Name1 
{
 [CompilerGenerated] 
get { return this.k__BackingField; }
 }

鉴于伊始化默许值实在构造函数中赋值的,所以跟属性只读不要紧。

机动只读属性暗中认可初步化

应用方法:

public string Name1 { get; } = "hello world";

编写翻译器生成代码如下:

[CompilerGenerated] 
private readonly string kBackingField; 
public Customer() 
{
 this.kBackingField = "hello world";
 } 
public string Name1 
{
 [CompilerGenerated] 
get { return this.k__BackingField; }
 }

鉴于开首化暗许值实在构造函数中赋值的,所以跟属性只读不妨。

表明式为宗旨的性质(赋值)

应用方式:

public string Name2 => "hello world";

编写翻译器生成代码如下:

public string Name2
{
     get { return "hello world"; }
}

编写翻译器只生成了个只读属性

字符串格式化

// 字符串格式化可以这样写:
var s1 = $"{p.Name} is {p.Age} year{{s}} old";

var s2 = $"{p.Name,20} is {p.Age:D3} year{{s}} old";

var s3 = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";

表明式为宗旨的函数

利用方式:

Body Get(int x, int y) => new Body(1 + x, 2 + y);

编译器生成如下:

private Program.Body Get(int x, int y)
{
    return new Program.Body(1 + x, 2 + y);
}

简化了单行方法的编辑,省去写大括号的素养。

并且援助未有再次回到值的写法: 

void OutPut(int x, int y) => Console.WriteLine("hello world");

也协理异步函数的编排:

async void OutPut(int x, int y) => await new Task(() => Console.WriteLine("hello wolrd"));

表明式为重点的函数

动用方式:

Body Get(int x, int y) => new Body(1 + x, 2 + y);

编写翻译器生成如下:

private Program.Body Get(int x, int y)
{
    return new Program.Body(1 + x, 2 + y);
}

简化了单行方法的编辑,省去写大括号的造诣。

再便是接济未有再次来到值的写法: 

void OutPut(int x, int y) => Console.WriteLine("hello world");

也支撑异步函数的编排:

async void OutPut(int x, int y) => await new Task(() => Console.WriteLine("hello wolrd"));

静态类导入

本条相比较易于明白,便是2遍性导入某项目标享有静态成员,然后在后头的代码中一向使用,比如:

using static System.Console;
class Program
{
      static void Main(string[] args}
      {
            WriteLine("hello world");
      }
}

nameof 表达式

WriteLine(nameof(DayOfWeek.Friday));  // 输出 Friday

static void Main(string[] args)
{
    throw new ArgumentNullException(nameof(args), "ArgumentNullException");
}

上边示例代码运营结果:
未经处理的非凡: System.ArgumentNullException: ArgumentNullException
参数名: ** args**

表明式为重点的性质(赋值)

动用情势:

public string Name2 => "hello world";

编译器生成代码如下:

public string Name2 
{ 
get { return "mushroomsir"; }
 }

编写翻译器只生成了个只读属性。

表明式为重点的特性(赋值)

动用办法:

public string Name2 => "hello world";

编写翻译器生成代码如下:

public string Name2 
{ 
get { return "mushroomsir"; }
 }

编写翻译器只生成了个只读属性。

Null 条件运算符

运用办法:

Customer cust = new Customer();
if (cust != null)
{
      string name = cust.Name;
}

等同于:

Customer cust = new Customer();
string name = cust?.Name;

可以和??组合起来使用:

if (customer?.Face()?? false)

仍可以3个一起用

int? Length = customer?.Name?.Length;

本条语法糖目标是在对象使用前检查是或不是为null,要是目的为空,则赋值给变量为宿舍,所以例子中须求3个足以为空的Int类型,即int?
比方目的不为空,则调用对象的成员取舍,并赋值给变量

字典开头化器

static void Main(string[] args)
{
    var strings = new Dictionary<string, string>()
    {
        ["ABC"] = "abc",
        ["DEF"] = "def"
    };

    foreach (var s in strings)
    {
        WriteLine(s.Key + ": " + s.Value);
    }

    WriteLine();

    var numbers = new Dictionary<int, string>
    {
        [7] = "seven",
        [9] = "nine",
        [13] = "thirteen"
    };

    foreach (var n in numbers)
    {
        WriteLine(n.Key + ": " + n.Value);
    }

    ReadKey();
}

地点示例代码输出结果为:

ABC: abc
DEF: def

7: seven
9: nine
13: thirteen

静态类导入

以此特点能够一回性导入某项目标具有静态成员,使静态成员在背后的代码中未有项目限制平昔行使,像使用本类型上面包车型地铁静态方法一样。

using static System.Console;
 class Program 
{ 
static void Main(string[] args) 
{
 WriteLine("hello wolrd"); 
}
}

编写翻译器生成代码如下:

private static void Main(string[] args)
 {
 Console.WriteLine("hello wolrd"); 
}

节约了品种名称的再度编写。

静态类导入

以此特点可以一遍性导入某项指标具有静态成员,使静态成员在后面包车型地铁代码中向来不项目限制从来行使,像使用本类型下边包车型大巴静态方法一样。

using static System.Console;
 class Program 
{ 
static void Main(string[] args) 
{
 WriteLine("hello wolrd"); 
}
}

编写翻译器生成代码如下:

private static void Main(string[] args)
 {
 Console.WriteLine("hello wolrd"); 
}

节约了品种名称的重新编写。

字符串格式化

在上面包车型客车例证中,String.Format
某个不便于的地点是:必须输入“String.Format”,
使用{0}点位符,必须按梯次来格式化,那点比较便于失误:

var s = String.Format("{0} is {1} year old", p.Name, p.Age);

新的语法糖能够如此使用:

var s = $"{p.Name} is {p.Age} year old";

比较有意思的是,新格式方法还援救任何表明式的直接赋值:

var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";

那么些过滤器

catch (ArgumentNullException e) when (e.ParamName == “…”)  
{  
}  

假定括号表明式(when)的结果为 true 时,才实施对应 catch
块中的语句,不然继续寻找处理程序。

static void Main(string[] args)
{
    try
    {
        throw new ArgumentNullException(nameof(args), "ArgumentNullException");
    }
    catch (ArgumentNullException ex) when (ex.ParamName == "arges")
    {
        WriteLine("ArgumentNullException");
    }
    catch (Exception ex) when (ex.InnerException == null)
    {
        WriteLine("Exception");
    }
}

演示代码输出结果为:
Exception

Null条件运算符

选拔格局:

Customer customer = new Customer();
 string name3 = customer?.Name;

等同于:

Customer customer = new Customer();
if (customer1 != null)
{
    string name = customer1.Name;
}

能够和??组合起来使用:

if (customer?.Face2()??false)

还足以1个联合用:

int? Length = customer?.Name?.Length;

也足以方法调用:

customer?.Face();

以此语法糖的指标是在对象使用前检查是或不是为null。假诺指标为空,则赋值给变量为空值,所以例子中须要一个得以为空的int类型、即int?。

一经指标不为空,则调用对象的积极分子取值,并赋值给变量。

Null条件运算符

运用方式:

Customer customer = new Customer();
 string name3 = customer?.Name;

等同于:

Customer customer = new Customer();
if (customer1 != null)
{
    string name = customer1.Name;
}

能够和??组合起来使用:

if (customer?.Face2()??false)

仍是能够二个体协会同用:

int? Length = customer?.Name?.Length;

也足以方法调用:

customer?.Face();

那个语法糖的目标是在对象使用前检查是否为null。1经指标为空,则赋值给变量为空值,所以例子中须求三个足以为空的int类型、即int?。

假如指标不为空,则调用对象的积极分子取值,并赋值给变量。

目录的起始化

利用List时,纵然能够因此下边包车型地铁法子书写,能够编写翻译通过,但依然会抛极度,使用方法:

var numbers = new List<string> { [7] = "seven", [9] ="nine", [13] ="thirteen"};

编译器生成代码:

List list = new List(); 
list[7] = "seven";
 list[9] = "nine"; 
list[13] = "thirteen";

Dictionary 能够进行,因为两岸内部索引机制不雷同:

var numbers = new Dictionary<int, string> {[7] = "seven",[9] = "nine",[13] = "thirteen";

在 catch 和 finally 块使用首要字 await

C# 陆.0 在此以前catch和finally块中是不能够用 await
关键词的。现在我们得以再那多个地点使用await了。

public async void Info()
{
    try
    {
        //Do something
    }
    catch (Exception)
    {
        await SumPageSizesAsync();
    }
    finally
    {
        await SumPageSizesAsync();
    }
}

private async Task SumPageSizesAsync()
{
    string url = "http://api.xxxx.com/";
    HttpClient client = new HttpClient();
    Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
    byte[] urlContents = await getContentsTask;
}

字符串格式化

String.Format有个别不便宜的地点是:必须输入”String.Format”,使用{0}占位符、必须逐1来格式化、那点简单出错。

var s = String.Format("{0} is {1} year {{s}} old", p.Name, p.Age);

新的语法糖使用起来相对更轻松些:

var s = $"{p.Name} is {p.Age} year{{s}} old";

编译器生成如下,和事先未曾分别:

var s = String.Format("{0} is {1} year{{s}} old", p.Name, p.Age);

幽默的是,新格式化方式还援救任何表达式的直接赋值:

var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";

字符串格式化

String.Format有个别不便利的地点是:必须输入”String.Format”,使用{0}占位符、必须逐壹来格式化、这一点不难失误。

var s = String.Format("{0} is {1} year {{s}} old", p.Name, p.Age);

新的语法糖使用起来相对更自在些:

var s = $"{p.Name} is {p.Age} year{{s}} old";

编写翻译器生成如下,和后面从未区分:

var s = String.Format("{0} is {1} year{{s}} old", p.Name, p.Age);

幽默的是,新格式化方式还支持任何表明式的直白赋值:

var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";

这个过滤器 when

利用方法:

try
{ 
throw new ArgumentException("string error");
 }
 catch (ArgumentException e) when (myfilter(e))
 { 
Console.WriteLine(e.Message);
 }

static bool myfilter(ArgumentException e)
 { 
return false;
 }

When语法功能是:在进入到catch在此以前、验证when括号里myfilter方法再次回到的bool,假使回去true继续运行,false不走catch直接抛出十三分。

运用那些filter能够更好的判定3个张冠李戴是后续处理依旧重新抛出去。依据以前的做法,在catch块内如需再度抛出去,须求重新throw出去,那时的错误源是捕捉后在抛的,而不是本来的,有了when语法就足以一直定位到错误源。

索引初步化

List尽管这么写能够编写翻译通过,可是会抛非常的,使用方法:

var numbers = new List<string> { [7] = "seven", [9] = "nine", [13] = "thirteen" };

编写翻译器生成代码如下:

List list = new List(); 
list[7] = "seven";
 list[9] = "nine"; 
list[13] = "thirteen";

Dictionary能够实施,因为两岸内部索引机制不1致:

 var numbers = new Dictionary<int, string> {[7] = "seven",[9] = "nine",[13] = "thirteen" };

编写翻译器生成代码:

 Dictionary<int, string> dictionary2 = new Dictionary<int, string>();
    dictionary2[7] = "seven";
    dictionary2[9] = "nine";
    dictionary2[13] = "thirteen";
    Dictionary<int, string> dictionary = dictionary2;

索引开头化

List纵然这么写能够编写翻译通过,不过会抛万分的,使用格局:

var numbers = new List<string> { [7] = "seven", [9] = "nine", [13] = "thirteen" };

编写翻译器生成代码如下:

List list = new List(); 
list[7] = "seven";
 list[9] = "nine"; 
list[13] = "thirteen";

Dictionary能够执行,因为两方内部索引机制不均等:

 var numbers = new Dictionary<int, string> {[7] = "seven",[9] = "nine",[13] = "thirteen" };

编写翻译器生成代码:

 Dictionary<int, string> dictionary2 = new Dictionary<int, string>();
    dictionary2[7] = "seven";
    dictionary2[9] = "nine";
    dictionary2[13] = "thirteen";
    Dictionary<int, string> dictionary = dictionary2;

nameof表达式

突发性会必要程序中部分成员的字符串名称,比如抛出ArgumentNullException格外的时候,想知道ArgumentNullException类型的字符串名称,这时候就能够用nameof获取字符

串“ArgumentNullException”。今后做法都是手动复制一下,但重构改名的时候便于忘记变更字符串,使用nameof就足以免止了。

string name = "";
Console.WriteLine(nameof(name));

可怜过滤器when

选用形式:

 try 
{ 
throw new ArgumentException("string error");
 }
 catch (ArgumentException e) when (myfilter(e))
 { 
Console.WriteLine(e.Message);
 }

static bool myfilter(ArgumentException e)
 { 
return false;
 }

When语法效用是:在进入到catch在此之前、验证when括号里myfilter方法重返的bool,借使回到true继续运转,false不走catch直接抛出分外。

使用那一个filter能够更好的判断多少个谬误是持续处理或许再度抛出去。遵照以前的做法,在catch块内如需另行抛出去,须要再度throw出去,这时的错误源是捕捉后在抛的,而不是原来的,有了when语法就可以直接固定到错误源。 

可怜过滤器when

利用方法:

 try 
{ 
throw new ArgumentException("string error");
 }
 catch (ArgumentException e) when (myfilter(e))
 { 
Console.WriteLine(e.Message);
 }

static bool myfilter(ArgumentException e)
 { 
return false;
 }

When语法功能是:在进入到catch以前、验证when括号里myfilter方法再次回到的bool,假如回去true继续运转,false不走catch直接抛出1二分。

采取这些filter可以更好的判定一个荒谬是后续处理依然重新抛出去。遵照以前的做法,在catch块内如需再次抛出去,需求重新throw出去,那时的错误源是捕捉后在抛的,而不是本来的,有了when语法就足以一向定位到错误源。 

catch和finally代码块内的Await

Await异步处理是在c#伍.0建议的,但无法在catch和finally代码块Nelly用,这一次在C#六.0翻新上支撑了。

运用形式:

    async void Solve()
    {
        try
        {
            await HttpMethodAsync();
        }
        catch (ArgumentException e)
        {
            await HttpMethodAsync();
        }
        finally
        {
            await HttpMethodAsync();
        }
    }

编译器把catch和finally的await生成到状态机里面包车型客车MoveNext()里面。原来里面唯有TaskAwaiter,现在多了二个。状态机里面的代码和原来的一样,只是更扑朔迷离了下,有趣味的童鞋可以先看下Async、Await剖析再去探索。

catch和finally代码块内的Await

Await异步处理是在c#五.0提出的,但不可能在catch和finally代码块内使用,本次在C#陆.0立异上扶助了。

使用办法:

    async void Solve()
    {
        try
        {
            await HttpMethodAsync();
        }
        catch (ArgumentException e)
        {
            await HttpMethodAsync();
        }
        finally
        {
            await HttpMethodAsync();
        }
    }

编写翻译器把catch和finally的await生成到状态机里面包车型客车MoveNext()里面。原来里面只有TaskAwaiter,今后多了三个。状态机里面包车型地铁代码和原来的如出一辙,只是更扑朔迷离了下,有趣味的童鞋可以先看下Async、Await剖析再去追究。

nameof表达式

选取方法:

string name = "";
Console.WriteLine(nameof(name));

决定台出口 “name”。

有时会必要程序中有个别分子的字符串名称,比如抛出ArgumentNullException格外的时候,想驾驭ArgumentNullException类型的字符串名称,那时候就足以用nameof获取字符

串“ArgumentNullException”。以往做法都以手动复制一下,但重构改名的时候便于忘记变更字符串,使用nameof就可避防止了。

当如下使用的时候,编写翻译器会只取最后的ZipCode。

nameof(person.Address.ZipCode)

编写翻译器生成如下代码:

Console.WriteLine("name");

nameof表达式

采用方式:

string name = "";
Console.WriteLine(nameof(name));

支配台出口 “name”。

奇迹会须求程序中部分成员的字符串名称,比如抛出ArgumentNullException万分的时候,想清楚ArgumentNullException类型的字符串名称,这时候就能够用nameof获取字符

串“ArgumentNullException”。未来做法都以手动复制一下,但重构改名的时候便于忘记变更字符串,使用nameof就足防止止了。

当如下使用的时候,编写翻译器会只取最终的ZipCode。

nameof(person.Address.ZipCode)

编写翻译器生成如下代码:

Console.WriteLine("name");

壮大方法

    using static System.Linq.Enumerable; //引入类型,而不是命名空间
    class Program
    {
        static void Main()
        {
            var range = Range(5, 17);                // Ok: 不是扩展方法
            var odd = Where(range, i => i % 2 == 1); // Error, 不在全局作用域里
            var even = range.Where(i => i % 2 == 0); // Ok
        }
    }

首先Enumerable是个静态类,里面是各样扩展方法,比如range。static的法力是把项指标静态成员二回性导入,rang固然是静态方法,但不能够导入,比如where。

因为扩大方法即便是一个静态方法,不过语法规定它看做三个实例方法运用(打点),所以不能够在全局功能域里当静态方法用,因而var
odd = Where(range, i => i % 二 == 一)是张冠李戴的。

然则static却能把品种的扩充方法作为增加方法本身剧中人物的效益导入进去,所以var
even = range.Where(i => i % 贰 == 0)是ok的。

此间或然某些有点绕,lz尽量写清楚,static新用法有三个职能:

  1. 把静态成员导入,但扩张方法相比较至极、排除在外。那时static是c#
    陆.0的新职能。
  2. 平等把扩充方法的命名空间导入,所以在集结上可以打点调用扩展方法。这是在此之前就有个别效益,而不是把扩张方法转成单纯的静态方法导入使用。

恢宏方法

    using static System.Linq.Enumerable; //引入类型,而不是命名空间
    class Program
    {
        static void Main()
        {
            var range = Range(5, 17);                // Ok: 不是扩展方法
            var odd = Where(range, i => i % 2 == 1); // Error, 不在全局作用域里
            var even = range.Where(i => i % 2 == 0); // Ok
        }
    }

首先Enumerable是个静态类,里面是种种扩张方法,比如range。static的职能是把品种的静态成员叁回性导入,rang即使是静态方法,但不能够导入,比如where。

因为扩张方法固然是二个静态方法,不过语法规定它当作三个实例方法应用(打点),所以无法在全局作用域里当静态方法用,由此var
odd = Where(range, i => i % 二 == 一)是漏洞百出的。

只是static却能把项指标壮大方法作为扩充方法本人角色的作用导入进去,所以var
even = range.Where(i => i % 2 == 0)是ok的。

此地只怕有些有点绕,lz尽量写清楚,static新用法有1个作用:

  1. 把静态成员导入,但扩充方法相比特出、排除在外。那时static是c#
    六.0的新职能。
  2. 同样把扩充方法的命名空间导入,所以在集聚上得以打点调用增加方法。那是事先就部分职能,而不是把扩张方法转成单纯的静态方法导入使用。

总结

看样子园子里有介绍的稿子,临时来兴趣了,下班后装置个社区版就钻研分享下。
尽管微软直接出新东西,但都以由下至上迭代的,所以读书起来是可怜快的。

 

参考

总结

总的来看园子里有介绍的篇章,近来来兴趣了,下班后装置个社区版就钻研分享下。
纵然微软直接出新东西,但都是由下至上迭代的,所以读书起来是不行快的。

 

参考

探索C#之多样导航

探索C#之种种导航

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图