public class Customer { public string First { get; } = "Jane"; public string Last { get; } = "Doe"; } 大家会好奇只读属性之前是怎么进行赋值的呢? 在构造函数中: public class Customer { public string Name { get; }; public Customer(string first, string last) { Name = first + " " + last; } }
表达式--函数体成员(Expression-bodied function members):
Lambda表达式可以被声明为表达式体以及组成常规函数体块。此功能能带来同样的便利函数类型成员。
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:
该功能允许导入所有要可访问类型的静态成员,使他们无需限定即可使用后面的代码中: 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); } }
法为扩展方法可用: 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
有时代码往往要做null检查。空条件运算符允许您访问成员,只有当接收者是非null元素,否则提供一个空的结果: int? length = customers?.Length; // null if customers is null Customer first = customers?[0]; // null if customers is null
空条件运算符为了方便,与空合并运算符?? 一起使用: int length = customers?.Length ?? 0; // 0 if customers is null
空条件操作符,具有短路的行为,也就是当前面的内容不为空的时候,后面紧跟着的链式成员才会被访问。 int? first = customers?[0].Orders.Count(); 这个例子是本质上相当于: int? first = (customers != null) ? customers[0].Orders.Count() : null;
当然null条件运算符本身可以被链接,如果有需要不止一次地检查null链中: int? first = customers?[0].Orders?.Count();
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: