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

开卷目录:

阅读目录:

自行属性私下认可早先化

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. 索引起始化
  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";

为了便于驾驭使用二.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"));

静态类导入

以此比较易于理解,正是1遍性导入某项目标持有静态成员,然后在前边的代码中央直机关接选取,比如:

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)

还是能一个共同用

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

本条语法糖目标是在对象使用前检查是还是不是为null,假若目的为空,则赋值给变量为宿舍,所以例子中须求二个足以为空的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";

相比有意思的是,新格式方法还帮助任何表明式的第2手赋值:

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。要是目的为空,则赋值给变量为空值,所以例子中须求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)

仍是能够2个联合用:

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# 6.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能够更好的论断2个张冠李戴是后续处理也许再次抛出去。依据之前的做法,在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));

11分过滤器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直接抛出13分。

选择这一个filter能够更好的论断3个荒唐是继承处理依旧再次抛出去。依据原先的做法,在catch块内如需重新抛出去,须要再行throw出去,那时的错误源是捕捉后在抛的,而不是本来的,有了when语法就能够一贯定位到错误源。 

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剖析再去追究。

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剖析再去追究。

nameof表达式

应用方法:

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

操纵台出口 “name”。

有时会要求程序中1些分子的字符串名称,比如抛出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。

因为扩大方法固然是三个静态方法,可是语法规定它当作1个实例方法运用(打点),所以无法在全局成效域里当静态方法用,因而var
odd = Where(range, i => i % 二 == 一)是错误的。

不过static却能把项目标扩展方法作为扩充方法自己剧中人物的意义导入进去,所以var
even = range.Where(i => i % ② == 0)是ok的。

那里可能有点有点绕,lz尽量写清楚,static新用法有3个效益:

  1. 把静态成员导入,但扩张方法相比十分、排除在外。那时static是c#
    6.0的新功效。
  2. 1致把扩充方法的命名空间导入,所以在集聚上能够打点调用扩张方法。那是前面就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。

因为增添方法纵然是贰个静态方法,可是语法规定它当做二个实例方法应用(打点),所以无法在大局成效域里当静态方法用,由此var
odd = Where(range, i => i % 2 == 一)是不当的。

只是static却能把品种的扩展方法作为扩张方法本人角色的作用导入进去,所以var
even = range.Where(i => i % 二 == 0)是ok的。

那里可能有点有点绕,lz尽量写清楚,static新用法有2个成效:

  1. 把静态成员导入,但扩展方法相比奇特、排除在外。那时static是c#
    陆.0的新功用。
  2. 同样把扩展方法的命名空间导入,所以在集合上得以打点调用扩大方法。那是前面就部分职能,而不是把扩展方法转成单纯的静态方法导入使用。

总结

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

 

参考

总结

看到园子里有介绍的稿子,权且来兴趣了,下班后装置个社区版就研讨分享下。
即使微软一直出新东西,但都是由下至上迭代的,所以读书起来是尤其快的。

 

参考

探索C#之多种导航

探索C#之三种导航

网站地图xml地图