1、自动属性默认初始化
使用代码
public string Id { get; set; } = "001";
编译器生成的代码:
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; } } }
编译器是在实例化构造函数时初始化属性的。
2、自动只读属性默认初始化
使用代码
public string Name { get; } = "hello world";
编译器生成的代码
[CompilerGenerated] private readonly string kBackingField; public Customer() { this.kBackingField = "hello world"; } public string Name1 { [CompilerGenerated] get { return this.k__BackingField; } }
只读属性的赋值只能在构造函数中进行
3、表达式为主体的函数
使用代码
private static void Test() => Console.WriteLine("Hello World!!"); 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); }
如果函数体只有一行代码,采用表达式为主体的函数更加简洁
也支持异步函数的编写
async void OutPut(int x, int y) => await new Task(() => Console.WriteLine("hello wolrd"));
4、表达式为主体的属性(赋值)
使用代码
public string Name => "Frank";
编译器生成的代码
public string Name { get { return "Frank"; } }
可以看出这个属性是只读属性
5、静态类导入
使用代码
using static System.Console; private static void ListContacts(IEnumerable<Contact> contacts) { foreach (var contact in contacts) { WriteLine("{0,-6}{1,-6}{2,-20}{3,-10}", contact.Id, contact.Name, contact.EmailAddress, contact.PhoneNum); } WriteLine(); }
它山之石可以攻玉,C#这次把Java的这个比较好的语法特性借鉴了过来,赞一个。
编译器生成的代码
private static void ListContacts(IEnumerable<Contact> contacts) { foreach (var contact in contacts) { Console.WriteLine("{0,-6}{1,-6}{2,-20}{3,-10}", contact.Id, contact.Name, contact.EmailAddress, contact.PhoneNum); } Console.WriteLine(); }
6、NULL条件运算符
使用代码
Customer customer = new Customer(); string name = customer?.Name;
编译代码
Customer customer = new Customer(); if (customer != null) { string name = customer.Name; }
也可以和??组合起来使用
if (customer?.Face()??false)
还可以两个一起组合来使用
int? contactNameLen = contact?.Name?.Length;
这个语法糖的目的是在对象使用前检查是否为null。如果对象为空,则赋值给变量为空值,所以例子中需要一个可以为空的int类型、即int?。如果对象不为空,则调用对象的成员取值,并赋值给变量。
7、字符串格式化
String.Format有些不方便的地方是:必须输入"String.Format",使用{0}占位符、必须顺序来格式化、这点容易出错。
var contactInfo = string.Format("Id:{0} Name:{1} EmailAddr:{2} PhoneNum:{3}", contact.Id, contact.Name, contact.EmailAddress, contact.PhoneNum);
新的语法
var contactInfo2 = $"Id:{contact.Id} Name:{contact.Name} EmailAddr:{contact.EmailAddress} PhoneNum:{contact.PhoneNum}";
使用起来顺手多了,赞!
新格式化方式还支持任何表达式的直接赋值:
var contactInfo = $"Id:{contact.Id} Name:{(contact.Name.Length == 0 ? "Frank" : contact.Name)} EmailAddr:{contact.EmailAddress} PhoneNum:{contact.PhoneNum}";