随着C#语言的不断发展,新特性的加入使得编程变得更加高效和便捷。本文将介绍一些C#语言中新增的特性,这些特性可能并不像预期的那样令人惊叹,但它们确实为编程带来了更新的体验。可以通过下载VS 2014或安装Roslyn包来体验这些特性。请注意,一旦Roslyn下载包中添加了新特性,本文将进行更新,同样,如果某些特性被移除,本文也会相应地进行调整。
$符号的引入主要是为了简化基于字符串的索引操作。它并不是C#中动态特性的一部分,而是内部使用常规索引功能。为了更好地理解,来看一个例子:
var col = new Dictionary()
{
["first"] = "Hassan"
};
在旧的方式中,可能会这样赋值:
col["first"] = "Hassan";
而新的方式则更加简洁:
col.$first = "Hassan";
异常过滤器已经在VB编译器中得到了支持,现在C#也引入了这一特性。异常过滤器允许为catch块指定一个条件,只有当条件满足时,catch块才会被执行。这是最喜欢的一个特性,让来看一个例子:
try
{
throw new Exception("Me");
}
catch (Exception ex) if (ex.Message == "You")
{
// 这个不会被执行
}
catch (Exception ex) if (ex.Message == "Me")
{
// 这个会被执行
}
在C# 5中,为什么不能在catch和finally块中使用await关键字,似乎没有人知道原因。但现在,终于可以在这些块中使用await了。这非常棒,因为经常希望在catch块中执行I/O操作以记录异常原因,或者在finally块中执行类似的操作,而这些操作需要异步执行。
try
{
DoSomething();
}
catch (Exception)
{
await LogService.LogAsync(ex);
}
这个特性允许在表达式中间声明局部变量。这听起来很简单,但实际上解决了很多问题。过去在ASP.NET Web Forms项目中经常使用这样的代码:
long id;
if (!long.TryParse(Request.QueryString["Id"], out id)) { }
现在可以改进为:
if (!long.TryParse(Request.QueryString["Id"], out long id)) { }
这种声明的规则与C#中一般的声明规则相同。
这个特性允许在using语句中指定一个特定的类型,之后就可以在后续代码中访问该类型的所有静态成员,而不需要指定类名。
using static System.Console;
namespace ConsoleApplication10
{
class Program
{
static void Main(string[] args)
{
WriteLine("Hello World");
}
}
}
在C# 6中,可以像初始化字段一样初始化自动属性。需要注意的是,这种初始化不会导致setter函数被内部调用。后备字段的值是直接设置的。
public class Person
{
public string FirstName { get; set; } = "Hassan";
public string LastName { get; } = "Hashemi";
}
主构造函数将帮助减少将构造函数参数值捕获到类字段中以进行进一步操作的痛苦。这非常有用。它的主要目的是使用构造函数参数进行初始化。当声明一个主构造函数时,所有其他构造函数都必须使用: this()调用主构造函数。
class Person(string firstName, string lastName)
{
public string FirstName { get; set; } = firstName;
public string LastName { get; } = lastName;
}
注意,主构造函数的声明位于类的顶部。
// 旧的初始化方式
Dictionary oldWay = new Dictionary()
{
{ "Afghanistan", "Kabul" },
{ "United States", "Washington" },
{ "Some Country", "Some Capital city" }
};
// 新的初始化方式
Dictionary newWay = new Dictionary()
{
["Afghanistan"] = "Kabul",
["Iran"] = "Tehran",
["India"] = "Delhi"
};