孫廣東 2015.6.5
What's New in C# 6:
http://channel9.msdn.com/Shows/Visual-Studio-Toolbox/Whats-New-in-C-6
Cross Platform Development系列:
http://channel9.msdn.com/Shows/CZSK-videa/Cross-Platform-Development-1-Introduction
Developer Productivity: What's New in C# 6系列:
http://channel9.msdn.com/Series/Developer-Productivity-Whats-New-in-C-6/01
.NET Compiler Platform ("Roslyn") 的開(kāi)源源代碼:
https://github.com/dotnet/roslyn
New Language Features in C# 6 文章:
https://github.com/dotnet/roslyn/wiki/New-Language-Features-in-C%23-6在C#6.0中的新語(yǔ)言特性:
這篇文章介紹在C#6.0中的新語(yǔ)言特性。所有這些都是可在VS 2015中執(zhí)行。
1、Auto-property enhancements自動(dòng)屬性增強(qiáng)
1.1自動(dòng)屬性的初始值設(shè)定,現(xiàn)在您可以添加一個(gè)自動(dòng)屬性的初始值設(shè)定,就像字段:
public class Customer
{
public string First { get; set; } = "Jane";
public string Last { get; set; } = "Doe";
}
按寫(xiě)的順序執(zhí)行該初始值設(shè)定項(xiàng),就像普通的字段初始值設(shè)定項(xiàng)一樣,自動(dòng)屬性初始值設(shè)定項(xiàng)也不能引用this的
內(nèi)容–畢竟他們?cè)趯?duì)象之前執(zhí)行初始化。
1.2 只讀屬性的自動(dòng)屬性
public class Customer
{
public string First { get; } = "Jane";
public string Last { get; } = "Doe";
}
大家會(huì)好奇只讀屬性之前是怎么進(jìn)行賦值的呢? 在構(gòu)造函數(shù)中:
public class Customer
{
public string Name { get; };
public Customer(string first, string last)
{
Name = first + " " + last;
}
}
表達(dá)式--函數(shù)體成員(Expression-bodied function members):
Lambda表達(dá)式可以被聲明為表達(dá)式體以及組成常規(guī)函數(shù)體塊。此功能能帶來(lái)同樣的便利函數(shù)類型成員。
Expression bodies on method-like members:
public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public static implicit operator string(Person p) => p.First + " " + p.Last;
public void Print() => Console.WriteLine(First + " " + Last);
Expression bodies on property-like function members:
屬性和索引器:
public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);
Using static:
該功能允許導(dǎo)入所有要可訪問(wèn)類型的靜態(tài)成員,使他們無(wú)需限定即可使用后面的代碼中:
using static System.Console;
using static System.Math;
using static System.DayOfWeek;
class Program
{
static void Main()
{
WriteLine(Sqrt(3*3 + 4*4));
WriteLine(Friday - Monday);
}
}
這是偉大的,當(dāng)你有一組相關(guān)功能的特定域,它隨時(shí)使用。System.Math將是一個(gè)常見(jiàn)的例子。它還允許您直接訪
問(wèn)單個(gè)枚舉類型的值,如System.DayOfWeek的成員。
Extension methods:
擴(kuò)展方法是靜態(tài)方法,但應(yīng)作為實(shí)例方法使用。而不是global 范圍的擴(kuò)展方法,使用靜態(tài)特性使該類型的擴(kuò)展方
法為擴(kuò)展方法可用:
using static System.Linq.Enumerable; // The type, not the namespace
class Program
{
static void Main()
{
var range = Range(5, 17); // Ok: not extension
var odd = Where(range, i => i % 2 == 1); // Error, not in scope
var even = range.Where(i => i % 2 == 0); // Ok
}
}
Null-conditional operators
有時(shí)代碼往往要做null檢查??諚l件運(yùn)算符允許您訪問(wèn)成員,只有當(dāng)接收者是非null元素,否則提供一個(gè)空的結(jié)果:
int? length = customers?.Length; // null if customers is null
Customer first = customers?[0]; // null if customers is null
空條件運(yùn)算符為了方便,與空合并運(yùn)算符?? 一起使用:
int length = customers?.Length ?? 0; // 0 if customers is null
空條件操作符,具有短路的行為,也就是當(dāng)前面的內(nèi)容不為空的時(shí)候,后面緊跟著的鏈?zhǔn)匠蓡T才會(huì)被訪問(wèn)。
int? first = customers?[0].Orders.Count();
這個(gè)例子是本質(zhì)上相當(dāng)于:
int? first = (customers != null) ? customers[0].Orders.Count() : null;
當(dāng)然null條件運(yùn)算符本身可以被鏈接,如果有需要不止一次地檢查null鏈中:
int? first = customers?[0].Orders?.Count();
請(qǐng)注意,?操作符后面的調(diào)用(用括號(hào)括起的參數(shù)列表)無(wú)法立即執(zhí)行–這將導(dǎo)致太多的句法歧義。因此,直接調(diào)
用一個(gè)委托,如果它的存在,只有不工作的方式。但是,您可以通過(guò)調(diào)用委托方法:
if (predicate?.Invoke(e) ?? false) { … }
我們期望這種模式的一個(gè)非常普遍的使用將在觸發(fā)事件上:
PropertyChanged?.Invoke(this, args);
String interpolation字符串插值:
String.Format 是非常靈活的和有用的,但他們使用的是有點(diǎn)笨拙而且容易出錯(cuò)。尤其不幸的是使用{0}等占位符
格式字符串,它必須單獨(dú)行上提供的參數(shù):
var s = String.Format("{0} is {1} year{{s}} old", p.Name, p.Age);
字符串插值,您可以把表達(dá)式在正確的地方,通過(guò)"holes"直接在字符串:
var s = $"{p.Name} is {p.Age} year{{s}} old";
就像String.Format ,可選的對(duì)齊方式和格式說(shuō)明符可以得到:
var s = $"{p.Name,20} is {p.Age:D3} year{{s}} old";
內(nèi)容可以幾乎是任何表達(dá)式,甚至包括其他字符串:
var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";
Notice that the conditional expression is parenthesized, so that the : "s" doesn’t get confused
with a format specifier.
請(qǐng)注意,是帶圓括號(hào)的條件表達(dá)式,以便 : "s" 不混亂格式說(shuō)明符。
nameof expressions:
(if x == null) throw new ArgumentNullException(nameof(x));
WriteLine(nameof(person.Address.ZipCode)); // prints "ZipCode"
Index initializers:
對(duì)象和集合初始值設(shè)定項(xiàng)可用于以聲明方式初始化字段和屬性,或給集合一組元素。使用索引器初始化字典和其
他對(duì)象不優(yōu)雅。我們正在添加新對(duì)象初始值設(shè)定項(xiàng)的語(yǔ)法允許您通過(guò)任何索引器,它的新對(duì)象設(shè)置鍵的值:
var numbers = new Dictionary<int, string> {
[7] = "seven",
[9] = "nine",
[13] = "thirteen"
};
Exception filters
功能早VB 有. F#有. 現(xiàn)在C#中也有.
try { … }
catch (MyException e) when (myfilter(e))
{
…
}
private static bool Log(Exception e) { /* log it */ ; return false; }
…
try { … } catch (Exception e) when (Log(e)) {}
Await in catch and finally blocks:
Resource res = null;
try
{
res = await Resource.OpenAsync(…); // You could do this.
…
}
catch(ResourceException e)
{
await Resource.LogAsync(res, e); // Now you can do this …
}
finally
{
if (res != null) await res.CloseAsync(); // … and this.
}
Extension Add methods in collection initializers:
Improved overload resolution: