VS2015预览版中的C#6.0 新功能(三)
Using static
使用using StaticClass,你可以访问StaticClass类里的static成员而不需要指定类的名字,来看下面的例子
using System.Console; namespace CSharp6_0 { class UsingStatic { public void PrintMsg(string message) { WriteLine(message); } } }
在本例中,通过在一开始声明using System.Console; 在PrintMsg方法中就可以直接访问Console类的WriteLine方法了,而不需要使用Console.WriteLine。
这个语法糖的一个用处就是对于扩展方法,可以只引入一个扩展类中的扩展方法,而不是按命名空间引入整个命名空间的。
索引初始化器
对象和集合初始化器在初始化对象的属性,域或者给集合一组初始元素时,非常方便有效,而对于字典和带有索引器的对象,就不是那么方便。在6.0中,为对象初始化器引入了新的语法来通过索引器根据key设置value,下面是一个例子
class IndexerIntializer { public void Show() { var dictionary = new Dictionary<int, string> { [0] = "first", [2] = "third", }; Console.WriteLine(dictionary[0]); Console.WriteLine(dictionary[1]);//willthrow exception since it is not set. Console.WriteLine(dictionary[2]); } }
例子中在创建字典对象时,使用索引初始化器为其第一个元素和第三个元素设置了值.
异常过滤器
F#和VB中都具有异常过滤器,在c#6.0中也加入了这个功能,这样我们就能够写出如下所示的代码
try { … } catch (MyException e) if (myfilter(e)) { … }
只有if中的myfilter返回true,才会执行对应的catch语句块,否则异常会继续抛出。异常过滤器在需要先catch,然后再throw出去的情况下,非常适用,因为它对异常的stack信息没有改变,在后面的处理中,能够取到异常最初抛出的地方而非重新抛出的地方。来看下面的一个例子
internal class ExceptionFilter { private void ThrowException(string argument) { if (argument == null) { throw new ArgumentNullException("argument is null"); } } private bool LogExcetion(Exception ex) { Console.WriteLine("Logger: " +ex.Message); return false; } public void Show() { try { ThrowException(null); } catch (ArgumentNullException ex) if (LogExcetion(ex)) { Console.WriteLine("Only print this when the filter return true"); } } }
这个ExceptionFilter类有三个方法,其中ThrowException是异常抛出点,LogException是异常过滤函数,Show函数则调用ThrowException函数并使用LogException函数写log。
下面是调用Show函数的执行结果
从截图中可以看出,Show函数的catch块并没有执行,因为LogException函数返回false。异常的stack信息保存完成。
在catch和finally里使用await
在c#5.0中,await关键字是不能在catch和finally语句块中使用的,在6.0中这个限制已经没有了,如下所示你可以把它用在catch和finally语句块中了
internal class AwaitInCatchAndFinally { public async void Show() { try { await OpenAsync(); // You could do this. } catch (Exception e) { await ProcessExceptionAsync(e); // Now you can do this … } finally { await CleanAsync(); //and this } } private Task ProcessExceptionAsync(Exception e) { return new TaskFactory().StartNew(() => Console.WriteLine("ProcessExceptionAsync: " + e.Message)); } private Task CleanAsync() { return new TaskFactory().StartNew(() => Console.WriteLine("CleanAsync is called ")); } private Task OpenAsync() { throw new Exception("exception happened."); } }
在本例中,await方法用在了catch和finally语句块中,下面是该程序的执行结果
结构体中的无参构造函数
之前struct对构造函数有一下的限制:
- 不能显示声明无参的构造函数
- 有参构造函数必须为所有的属性赋值
在c#6.0中,可以在struct中声明一个无参构造函数,下面是一个例子
internal struct StructParameterlessCtor { public int CPUCount { get; set; } public string Band { get; set; } public StructParameterlessCtor(int countOfCPU, string band) { CPUCount = countOfCPU; Band = band; } public StructParameterlessCtor() { CPUCount = 1; Band = "DELL"; } }
这个struct中,有两个构造函数,一个是有参的,一个是无参的,无论是有参还是无参的都必须为所有的属性赋值。这里无参构造函数也可以像下面那样调用有参的构造函数:
public StructParameterlessCtor() : this(1, "DELL") { }
struct中的无参构造函数只有在显示使用new运算符时才会被调用, default(StructParameterlessCtor) 和 new StructParameterlessCtor[...] 都不会调用无参构造函数。