C#6.0新特性

C#6.0新特性

原文:New features in C# 6.0

0. 导言

这篇文章涵盖C#6.0的新语言特性,一个代码名为“Roslyn”的新编译器被引入。这个编译器的源码是开源的,可以在Codeplex 网站下载(https://roslyn.codeplex.com/

C#6.0新特性列表

我们可以一个一个讨论这些新特性,但首先,下面列出C#6.0的新特性:

  • 自动属性初始化器
  • 主构造函数
  • 字典初始化器
  • 申明表达式
  • 静态Using
  • catch块中的await
  • 异常过滤器
  • 检查NULL值的条件访问操作符

1. 自动属性初始化器

Before

初始化一个自动属性的唯一方法是实现一个显式的构造函数,在里面设置属性。

public class AutoPropertyBeforeCsharp6
{
    private string _postTitle = string.Empty;
    public AutoPropertyBeforeCsharp6()
    {
        //assign initial values
        PostID = 1;
        PostName = "Post 1";
    }

    public long PostID { get; set; }

    public string PostName { get; set; }

    public string PostTitle
    {
        get { return _postTitle; }
        protected set
        {
            _postTitle = value;
        }
    }
}

After

在C#6.0中,带初始值的自动实现属性初始化不需要必须写构造体,我们能简化上面的例子:

public class AutoPropertyInCsharp6
{
    public long PostID { get;  } = 1;

    public string PostName { get; } = "Post 1";

    public string PostTitle { get; protected set; } = string.Empty;
}

2. 主构造函数

我们主要用构造函数初始化里面的值(接受参数值并赋值这些参数到实例属性)

Before

public class PrimaryConstructorsBeforeCSharp6
{
    public PrimaryConstructorsBeforeCSharp6(long postId, string postName, string postTitle)
    {
        PostID = postId;
        PostName = postName;
        PostTitle = postTitle;
    }

    public long PostID { get; set; }
    public string PostName { get; set; }
    public string PostTitle { get; set; }
}

After

public class PrimaryConstructorsInCSharp6(long postId, string postName, string postTitle)
{        
    public long PostID { get;  } = postId;
    public string PostName { get; } = postName;
    public string PostTitle { get;  } = postTitle;
}

在C#6.0中,主构造函数给我们一个简写语法来定义带参数的构造函数,每个类仅允许一个主构造函数。
如果你仔细看上面的例子,会发现我们把参数初始化移动到了类名旁边。

你可能得到以下错误“Feature ‘primary constructor’ is only available in ‘experimental’ language version.”解决这个问题,我们需要编辑SolutionName.csproj文件来去除这个错误,你不得不做的是在WarningTag后面添加额外的设置。

<LangVersion>experimental</LangVersion>

Feature 'primary constructor' is only available in 'experimental' language version

3. 字典初始化器

Before

写一个dictionary初始化器的旧方法是:

public class DictionaryInitializerBeforeCSharp6
{
    public Dictionary<string, string> _users = new Dictionary<string, string>()
    {
        {"users", "Venkat Baggu Blog" },
        {"Features", "Whats new in C# 6" }
    };
}

After

我们可以像定义数组那样用方括号定义dictionary初始化器

public class DictionaryInitializerInCSharp6
{
    public Dictionary<string, string> _users { get; } = new Dictionary<string, string>()
    {
        ["users"]  = "Venkat Baggu Blog",
        ["Features"] =  "Whats new in C# 6"
    };
}

4. 声明表达式

Before

public class DeclarationExpressionsBeforeCShapr6()
{
    public static int CheckUserExist(string userId)
    {
        //Example 1
        int id;
        if (!int.TryParse(userId, out id))
        {
            return id;
        }
        return id;
    }

    public static string GetUserRole(long userId)
    {
        ////Example 2
        var user = _userRepository.Users.FindById(x => x.UserID == userId);
        if (user!=null)
        {
            // work with address ...

            return user.City;
        }
    }
}

在C#6.0中,你能在表达式中声明一个本地变量。使用声明表达式我们也可以在if语句和各种循环语句中声明变量

public class DeclarationExpressionsInCShapr6()
{
    public static int CheckUserExist(string userId)
    {
        if (!int.TryParse(userId, out var id))
        {
            return id;
        }
        return 0;
    }

    public static string GetUserRole(long userId)
    {
        ////Example 2
        if ((var user = _userRepository.Users.FindById(x => x.UserID == userId) != null)
        {
            // work with address ...

            return user.City;
        }
    }
}

5. 静态Using

Before

对于静态成员,你不需要为了调用方法而弄一个对象实例,你用如下语法:

TypeName.MethodName
public class StaticUsingBeforeCSharp6
{
    public void TestMethod()
    {
        Console.WriteLine("Static Using Before C# 6");
    }
}

After

在C#6.0中,你能够不用类型名就使用静态成员,你能够在namespaces中引入静态类

如果你看下面的例子,我们移动静态Console类到namespace中:

using System.Console;
namespace newfeatureincsharp6
{
    public class StaticUsingInCSharp6
    {
        public void TestMethod()
        {
            WriteLine("Static Using Before C# 6");
        }
    }
}

6. 在catch块中用await

在C#6.0之前,await关键字不允许在catchinally块中,在C#6.0中,我们终于能在catchfinally块中用await关键字。

try
{           
    //Do something
}
catch (Exception)
{
    await Logger.Error("exception logging")
}

7. 异常过滤器

异常过滤器允许你在catch块执行前检查if条件

考虑一个例子,现在我们有一个异常,要检查是否InnerException null,然后执行catch

//Example 1
try
{
    //Some code
}
catch (Exception ex) if (ex.InnerException != null)
{
    //Do work

}

//Before C# 6 we write the above code as follows

//Example 1
try
{
    //Some code
}
catch (Exception ex)
{
    if(ex.InnerException != null)
    {
        //Do work;
    }
}

8. 检查NULL值的条件访问操作符

考虑一个例子,我们想要基于UserIDUserRanking是否为null

Before

var userRank = "No Rank";
if(UserID != null)
{
    userRank = Rank;
}
//or
var userRank = UserID != null ? Rank : "No Rank"

After

var userRank = UserID?.Rank ?? "No Rank";
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值