【www.30064.com】0语法糖剖析,0新增语法糖

阅读目录:

开卷目录:

电动属性暗中认可起初化

动用办法:

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

【www.30064.com】0语法糖剖析,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 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. www.30064.com,电动属性暗中同意开始化
  2. 活动只读属性暗许早先化
  3. 表明式为重心的函数
  4. 表明式为重点的性质(赋值)
  5. 静态类导入
  6. Null条件运算符
  7. 字符串格式化
  8. 索引发轫化
  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";

为了方便精通使用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;
    }
}
} 

 从转变代码中得以见见编写翻译器是在实例构造函数时,初始化属性消息的。

机动属性暗中同意起头化

应用方法:

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

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

表达式为重心的函数

运用格局:

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"));

静态类导入

其一相比较易于精通,就是一遍性导入某项目标持有静态成员,然后在背后的代码中央直机关接选用,比如:

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)

还足以三个1块用

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

以此语法糖指标是在指标使用前检查是不是为null,借使指标为空,则赋值给变量为宿舍,所以例子中须要3个得以为空的Int类型,即int?
1经目的不为空,则调用对象的成员取舍,并赋值给变量

字典发轫化器

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

节省了类小名称的重新编写。

静态类导入

其1性格能够1回性导入某项指标具备静态成员,使静态成员在背后的代码中一贯不项目限制一向选取,像使用本类型上面包车型地铁静态方法一样。

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)

还足以三个体协会同用:

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

也能够方法调用:

customer?.Face();

以此语法糖的指标是在对象使用前检查是或不是为null。1旦目的为空,则赋值给变量为空值,所以例子中需求2个得以为空的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。如果目的为空,则赋值给变量为空值,所以例子中须要多个方可为空的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 能够推行,因为两者内部索引机制不1样:

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}占位符、必须逐项来格式化、那一点不难失误。

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能够越来越好的判定二个荒谬是后续处理依然重新抛出去。依据从前的做法,在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能够推行,因为两岸内部索引机制不平等:

 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直接抛出非凡。

动用这么些filter能够越来越好的判定2个漏洞非常多是后续处理还是再次抛出去。依照以前的做法,在catch块内如需重新抛出去,要求重新throw出去,那时的错误源是捕捉后在抛的,而不是原本的,有了when语法就足以一向定位到错误源。 

catch和finally代码块内的Await

Await异步处理是在c#5.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剖析再去研究。

catch和finally代码块内的Await

Await异步处理是在c#5.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”。

突发性会需求程序中1些分子的字符串名称,比如抛出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的功用是把项目标静态成员1遍性导入,rang纵然是静态方法,但不能够导入,比如where。

因为扩充方法即便是一个静态方法,可是语法规定它当做一个实例方法运用(打点),所以不可能在大局功用域里当静态方法用,因而var
odd = Where(range, i => i % 2 == 一)是不当的。

可是static却能把品种的扩展方法作为扩充方法本人剧中人物的成效导入进去,所以var
even = range.Where(i => i % 2 == 0)是ok的。

那里只怕有个别有点绕,lz尽量写清楚,static新用法有2个职能:

  1. 把静态成员导入,但扩张方法比较奇特、排除在外。那时static是c#
    陆.0的新功效。
  2. 1如既往把扩充方法的命名空间导入,所以在集合上得以打点调用扩大方法。那是在此之前就有的职能,而不是把扩充方法转成单纯的静态方法导入使用。

扩张方法

    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。

因为扩充方法即使是3个静态方法,不过语法规定它看作三个实例方法应用(打点),所以无法在大局功用域里当静态方法用,由此var
odd = Where(range, i => i % 二 == 壹)是不当的。

而是static却能把品种的扩展方法作为增添方法自个儿剧中人物的遵守导入进去,所以var
even = range.Where(i => i % 二 == 0)是ok的。

这里也许有点有点绕,lz尽量写清楚,static新用法有一个职能:

  1. 把静态成员导入,但扩充方法对比特殊、排除在外。那时static是c#
    六.0的新成效。
  2. 一样把扩展方法的命名空间导入,所以在集结上能够打点调用扩大方法。这是在此以前就有个别效益,而不是把扩充方法转成单纯的静态方法导入使用。

总结

探望园子里有介绍的稿子,一时来兴趣了,下班后安装个社区版就商讨分享下。
纵然微软一贯出新东西,但都以由下至上迭代的,所以读书起来是极快的。

 

参考

总结

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

 

参考

探索C#之七种导航

探索C#之两种导航

发表评论

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

网站地图xml地图