C# 6.0 的新特性 已翻译 100%

oschina 投递于 2015/02/10 07:54 (共 4 段, 翻译完成于 03-05)
阅读 14827
收藏 56
C#
5
加载中

本文的内容包括引入C#6.0中的新的语言特性有哪些. 还有已经被引入的代码名称为 “Roslyn”新编译器. 编译器是开放源码的,并且可以从 codeplex 网站的这个地址下载到源代码: https://roslyn.codeplex.com/.

C# 6.0 中的新特性

我们可以对这些新特性一个一个的进行讨论,而首先要列出 C# 6.0 中这些特性的一个清单

  1. 自动的属性初始化器 Auto Property Initializer

  2. 主构造器 Primary Consturctor

  3. 字典初始化器 Dictionary Initializer

  4. 声明表达式 Declaration Expression

  5. 静态的Using Static Using

  6. catch 块中的 await

  7. 异常过滤器 Exception Filter

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

1. 自动的属性初始化器Auto Property initialzier

之前的方式

初始化一个自动属性Auto Property的唯一方式,就是去实现一个明确的构造器,在里面对属性值进行设置.

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;
        }
    }
}

有了这个特性之后的方式

使用 C# 6 自动实现的带有初始值的属性可以不用编写构造器就能被初始化. 我们可以用下面的代码简化上面的示例:

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

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

    public string PostTitle { get; protected set; } = string.Empty;
}
LeoXu
LeoXu
翻译于 2015/02/10 20:06
3

2. 主构造器

我们使用构造器主要是来初始化里面的值.(接受参数值并将这些参数值赋值给实体属性).

之前的方式

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; }
}

有了这个特性之后的方式

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 中, 主构造器为我们提供了使用参数定义构造器的一个简短语法. 每个类只可以有一个主构造器.

如果你观察上面的示例,会发现我们将参数初始化移动到了类名的旁边.

你可能会得到下面这样的错误“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

‘主构造器’只在‘实验’性质的语言版本中可用

LeoXu
LeoXu
翻译于 2015/02/10 20:20
1

3. 字典初始化器

之前的方式

编写一个字典初始化器的老办法如下

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

有了这个特性之后的方式

我们可以像数组里使用方括号的方式那样定义一个字典初始化器

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

4. 声明表达式

之前的方式

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 中你可以在表达式的中间声明一个本地变量. 使用声明表达式我们还可以在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

之前的方式

对于你的静态成员而言,没必要为了调用一个方法而去弄一个对象实例. 你会使用下面的语法

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

之后的方式

在 C# 6 中,你不用类名就能使用 静态成员 . 你可以在命名空间中引入静态类.

如果你看了下面这个实例,就会看到我们将静态的Console类移动到了命名空间中

using System.Console;
namespace newfeatureincsharp6
{
    public class StaticUsingInCSharp6
    {
        public void TestMethod()
        {
            WriteLine("Static Using Before C# 6");
        }
    }
}
LeoXu
LeoXu
翻译于 2015/02/10 20:35
1

6. catch块里面的await

C# 6 之前catch和finally块中是不能用 await 关键词的. 在 C# 6 中,我们终于可以再这两个地方使用await了.

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

7. 异常过滤器

异常过滤器可以让你在catch块执行之前先进行一个 if 条件判断.

看看这个发生了一个异常的示例,现在我们想要先判断里面的Exception是否为null,然后再执行catch块

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

}

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

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

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

看看这个实例,我们基于UserID是否不为null这个条件判断来提取一个UserRanking.

之前的方式

var userRank = "No Rank";
if(UserID != null)
{
    userRank = Rank;
}

//or

var userRank = UserID != null ? Rank : "No Rank"

有了这个特性之后方式

var userRank = UserID?.Rank ?? "No Rank";

C# 6.0中的新特性 第一次出现在 Venkat Baggu 博客 上.

LeoXu
LeoXu
翻译于 2015/02/10 20:47
2
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(65)

l
lindexi
http://blog.csdn.net/lindexi_gd/article/details/49716741?locationNum=9&fps=1
l
lindexi
https://msdn.microsoft.com/zh-cn/magazine/dn879355.aspx
p
padeoe
文中的PrimaryConstructor特性已经从C# 6.0正式版中移除了,改LangVersion也会报错。
C
CodingNinja

引用来自“joome”的评论

怎么复杂怎么整,为什么他们的理念是复杂呢?特征是越多越好么?把一个语言变成垃圾桶。垃圾越来越多,漏洞也越来越多,一门语言到底是稳定重要还是求新重要,一天到晚折腾语法,还写什么代码,写语言得了,,
真是自己学习能力差看到东西多就觉得复杂,怎么不说 C 语言有指针不安全大家都不要用?javascript 复杂?难道语法糖、特性这些东西会丧失稳定性?
C
CodingNinja

引用来自“大师兄悟空”的评论

开源Java的世界,为何要提这不争气的.NET??
.NET哪里不争气?任何语言都有其适用的领域,合理运用就是对的,非要大家都去讨论最流行的?那么前几年大家都讨论一度排名第一的 C 语言,别的语言不讨论也就不会流行,这样 C 语言永远保持第一,Java 都不用提了。
C
CodingNinja

引用来自“aeolusj”的评论

很久没用过c#,现在的语法可读性越来越差的感觉,比如最后一串问号的这个
var userRank = UserID?.Rank ?? "No Rank";让新人抓狂的节奏
拜托,这只是演示可以这样写。我能说 C 语言很多教科书上还写着:i+++++i 之类的吗?只是说能这样写而已,任何语言都能写出糟糕的可读性代码,而实际情况则是看人,好的程序员是不会这样写的
C
CodingNinja

引用来自“aeolusj”的评论

很久没用过c#,现在的语法可读性越来越差的感觉,比如最后一串问号的这个
var userRank = UserID?.Rank ?? "No Rank";让新人抓狂的节奏

引用来自“盛大的发生”的评论

微软老是改UI,然后就以为能卖个好价钱了。就像win 7 8 10一个德行
你懂什么是UI吗?==看着好无语。另外,Win 7 8 10 难道只是改 UI ?你看过它的内核?
C
CodingNinja
哈哈,看一些喷子的话都无厘头,笑死了,什么复杂度和cpp媲美,这和复杂度有什么关系?大多数都是语法糖,语法糖就是增加程序的可读性,从而减少程序代码出错的机会。
三日月
三日月

引用来自“大师兄悟空”的评论

开源Java的世界,为何要提这不争气的.NET??

引用来自“HYUO”的评论

Java8赶上6年前的.net 3.5没? Java8赶上6年前的.net 3.5没? Java8赶上6年前的.net 3.5没? Java8赶上6年前的.net 3.5没? Java8赶上6年前的.net 3.5没? Java8赶上6年前的.net 3.5没? 若是没有,何敢言“争气”?

引用来自“宇宙大将军”的评论

.net的排名赶上6年前的Java没?.net的排名赶上6年前的Java没?.net的排名赶上6年前的Java没? .net的排名赶上6年前的Java没?.net的排名赶上6年前的Java没?.net的排名赶上6年前的Java没?若是没有,为何不是“不争气”?

引用来自“三日月”的评论

什么排名?tiobe那个扯淡的排名吗?

引用来自“宇宙大将军”的评论

因为C#没排在Java前面,所以扯着你的蛋了吧? 要是C#排在Java前面,你就跪舔吧?

引用来自“三日月”的评论

回答我的问题,少在这跪舔java

引用来自“宇宙大将军”的评论

如果不是tiobe这个扯着你的蛋的排名,而是RedMonk这个可能也会扯你蛋的排名呢?跪舔者?
还是流行度啊,赢得了流行度就赢得了一切是吗?
宇宙大将军

引用来自“大师兄悟空”的评论

开源Java的世界,为何要提这不争气的.NET??

引用来自“HYUO”的评论

Java8赶上6年前的.net 3.5没? Java8赶上6年前的.net 3.5没? Java8赶上6年前的.net 3.5没? Java8赶上6年前的.net 3.5没? Java8赶上6年前的.net 3.5没? Java8赶上6年前的.net 3.5没? 若是没有,何敢言“争气”?

引用来自“宇宙大将军”的评论

.net的排名赶上6年前的Java没?.net的排名赶上6年前的Java没?.net的排名赶上6年前的Java没? .net的排名赶上6年前的Java没?.net的排名赶上6年前的Java没?.net的排名赶上6年前的Java没?若是没有,为何不是“不争气”?

引用来自“三日月”的评论

什么排名?tiobe那个扯淡的排名吗?

引用来自“宇宙大将军”的评论

因为C#没排在Java前面,所以扯着你的蛋了吧? 要是C#排在Java前面,你就跪舔吧?

引用来自“三日月”的评论

回答我的问题,少在这跪舔java
如果不是tiobe这个扯着你的蛋的排名,而是RedMonk这个可能也会扯你蛋的排名呢?跪舔者?
返回顶部
顶部