首页 > 代码库 > VS2015预览版中的C#6.0 新功能(三)

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对构造函数有一下的限制:

  1. 不能显示声明无参的构造函数
  2. 有参构造函数必须为所有的属性赋值

在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[...] 都不会调用无参构造函数。

 

VS2015预览版中的C#6.0 新功能(三)