C# 6.0 新特性 (三)

主构造函数

自动属性初始化表达式尤其适合与主构造函数结合使用。主构造函数为降低常见对象模式的繁琐程度提供了一种方法。此功能自五月以来已显著改进。更新包括:

  1. 主构造函数的可选实现主体:这将支持此前不受支持的主构造函数参数验证和初始化等。
  2. 取消字段参数:通过主构造函数参数对字段进行声明。(不将此功能按照已定义方式推出是正确的决定,因为它不再按照 C# 之前矛盾的方式强制遵循特定命名约定。)
  3. 支持表达式主体函数和属性(本文稍后将进行讨论)。

随着 Web 服务、多层应用程序、数据服务、Web API、JSON 及类似技术的普遍使用,类的一个普遍形式是数据传输对象 (DTO)。DTO 通常不会实现太多功能,而是专注于使数据存储简单化。它对于简单性的关注使得主构造函数极具新引力。例如,请看本示例中所示的固定 Pair 数据结构:

struct Pair<T>(T first, T second)
{
  public T First { get; } = first;
  public T Second { get; } = second;
  // Equality operator ...
}

构造函数定义 Pair(string first, string second) 已合并到类声明中。这会将构造函数参数指定为 first 和 second(均为类型 T)。属性初始化表达式中也引用了这些参数,并将参数分配给其对应的属性。当您发现此类定义的简单性、对不变性的支持以及必不可少的构造函数(所有属性/字段的初始化表达式)时,您将会了解到它是如何帮助您正确编写代码的。这将导致先前需要不必要的详细级别的常见模式得到显著改进。

主构造函数主体指定对主构造函数执行的操作。这将有助于您在主构造函数上实现通常在构造函数上可以实现的等同功能。例如,改进 Pair<T> 数据结构的可靠性的下一个步骤可能是提供属性验证。此类验证可以确保 Pair.First 的 null 值将无效。现在,CTP3 包括一个主构造函数主体(未声明的构造函数主体),如图 4 中所示。

实现主构造函数主体

struct Pair<T>(T first, T second)
{
  {
    if (first == null) throw new ArgumentNullException("first");
    First = first; // NOTE: Not working in CTP3
  }
  public T First { get; }; // NOTE: Results in compile error for CTP3
  public T Second { get; } = second;
  public int CompareTo(T first, T second)
  {
    return first.CompareTo(First) + second.CompareTo(Second);
  }
// Equality operator ...
}

为清晰起见,我将主构造函数主体置于类的第一个成员中。但这不是 C# 所要求的。主构造函数主体可以按与其他类成员相关的任意顺序显示。

只读属性的另一个功能尽管在 CTP3 中没有发挥作用,但您可以从构造函数内直接分配这些属性(例如,First = first)。这不仅仅限于主构造函数,而且还适用于所有构造函数成员。

支持自动属性初始化表达式的一个有趣的结果是,它解决了早期版本中出现的需要显式字段声明的多种情况。它没有解决一个最明显的问题,即需要对 setter 进行验证的情况。另一方面,几乎已不需要声明只读字段。现在,无论何时声明只读字段,只要需要该封装级别,您都可以将只读自动属性声明为私有。

CompareTo 方法具有参数 first 和 second,这好像与主构造函数的参数名称重复。由于主构造函数名称在自动属性初始化表达式作用域内,因此,first 和 second 似乎并不明确。幸运的是,实际情况并非如此。作用域规则将依据不同维度而定,而您之前在 C# 中并未看到。

在 C# 6.0 之前,作用域始终由代码内的变量声明放置来确定。参数在其帮助声明的方法中绑定,字段在类中绑定,在 if 语句中声明的变量由 if 语句条件主体绑定。

相比之下,主构造函数参数则由时间来绑定。主构造函数参数仅在执行主构造函数时为“活动”状态。此时间范围在主构造函数主体的情况中很明显。可能对于自动属性初始化表达式的情况不太明显。

但是,与作为 C# 1.0+ 中的类初始化表达式的一部分执行的转换为语句的字段初始化表达式类似,自动属性初始化表达式也通过同样的方式实现。换言之,主构造函数参数的作用域与类初始化表达式和主构造函数主体的生命周期绑定。在自动属性初始化表达式或主构造函数主体外部对主构造函数参数进行任何引用都将产生编译错误。

还有其他几个与主构造函数相关的概念需要牢记。只有主构造函数可以调用基构造函数。您可以使用主构造函数声明后跟的基本(上下文)关键字执行此操作:

class UsbConnectionException(
  string message, Exception innerException, HidDeviceInfo hidDeviceInfo):
    Exception  (message, innerException)
{
  public HidDeviceInfo HidDeviceInfo { get;  } = hidDeviceInfo;
}

如果指定其他构造函数,则构造函数调用链必须最后调用主构造函数。这意味着主构造函数不能具有此初始化表达式。假定主构造函数也不是默认构造函数,所有其他构造函数必须具有这些初始化表达式:

public class Patent(string title, string yearOfPublication)
{
  public Patent(string title, string yearOfPublication,
    IEnumerable<string> inventors)
    ...this(title, yearOfPublication)
  {
    Inventors.AddRange(inventors);
  }
}

希望这些示例有助于展示主构造函数简化了 C#。通过主构造函数,还有机会以简单的方式来执行简单的任务,而不是以复杂的方式来执行简单的任务。它偶尔也会让类包含多个主构造函数和调用链,致使代码不易于阅读。如果您遇到主构造函数语法使代码看起来更为复杂而不是简化代码的情况,那么请不要使用主构造函数。对于 C# 6.0 的所有增强功能,如果您有不喜欢的功能,或某个功能使您的代码不易于阅读,请不要使用该功能。

表达式主体函数和表达式属性

表达式主体函数是 C# 6.0 中的另一个语法精简形式。有一些函数不包括语句体,而是以函数声明后跟表达式的形式来实现。

例如,可以这样向 Pair<T> 类添加 ToString 方法的重写:

public override string ToString() => string.Format("{0}, {1}", First, Second);

表达式主体函数没有什么彻底更改。和 C# 6.0 中的大部分功能一样,它们旨在提供简化的语法,用于实现简单的情况。当然,表达式的返回类型必须与函数声明中定义的返回类型相匹配。在这种情况下,ToString 将返回一个字符串,这同函数实现表达式返回的结果一样。返回 void 或 Task 的方法应通过同样不会返回任何结果的表达式实现。

表达式主体简化不仅仅限于函数,您还可以使用表达式实现只读(仅包含 getter)属性——表达式属性。例如,可以将 Text 成员添加到 FingerPrint 类:

public string Text =>
  string.Format("{0}: {1} - {2} ({3})", TimeStamp, Process, Config, User);

其他功能

有一些功能不再计划针对 C# 6.0 实现:

  • 索引属性运算符 ($) 不再可用,并且不针对 C# 6.0 实现。
  • 尽管索引成员语法预期在 C# 6.0 的更高版本中回归,但它在 CTP3 中不起作用:

    var cppHelloWorldProgram = new Dictionary<int, string>
    {
    [10] = "main() {",
    [20] = "    printf(\"hello, world\")",
    [30] = "}"
    };

    主构造函数中的字段参数不再属于 C# 6.0。

  • 二进制数字文本和数字文本中的数字分隔符 (‘_’) 在正式发布之前尚不确定。

原文出处:http://msdn.microsoft.com/zh-cn/magazine/dn802602.aspx

时间: 2025-01-04 18:02:08

C# 6.0 新特性 (三)的相关文章

day07 MyEclipse 安装 jdk5.0 新特性

1.myeclipse的安装和使用 * eclipse:是一个免费的开发工具    * myeclipse:是一个收费的插件,破解myeclipse,        ** 安装目录的要求: 不能有中文和空格        ** 安装完成之后,选择一个工作空间 ,这个工作空间不能有中文和空格    * 破解myeclipse        ** 运行run.bat文件,但是运行之前,必须要安装jdk,通过配置环境变量 * myeclipse的使用        * 创建一个工程          

Servlet 3.0 新特性详解

转自:https://www.ibm.com/developerworks/cn/java/j-lo-servlet30/ Servlet 3.0 新特性详解 张 建平2010 年 4 月 23 日发布 WeiboGoogle+用电子邮件发送本页面 6 Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用于简化 Web 应用的开发和部署.其

开发者必看|Android 8.0 新特性及开发指南

背景介绍 谷歌2017 I/O开发者大会今年将于5月17-19日在美国加州举办.大会将跟往年一样发布最新的 Android 系统,今年为 Android 8.0.谷歌在今年3 月21日发布 Android 新系统开发者预览版时已给新系统取名为 Android O.自2008 年发布以来, Android 依靠 Google 的生态运作,全球市场份额在2016年底已超过85% .而近几年依靠 Android 发展起来的智能手机厂商不断增加, Android 生态大家庭也正在不断壮大. Androi

Servlet3.0新特性

时间:2017-1-4 16:51 --Servlet3.0新特性概述 前提:    1.MyEclipse1.0或以上版本    2.发布到Tomcat7.0或以上版本 步骤:    1.创建JavaEE6.0项目        在web.xml文件中有如下字样,即JavaEE6.0项目(是否Servlet3.0) <web-app version="3.0"> 新特性:    1.使用@WbServlet.@WebFilter.@WebListener三个注解来替代we

Servlet 3.0 新特性概述

Servlet 3.0 新特性概述 Servlet 3.0 作为 Java EE 6 规范体系中一员,随着 Java EE 6 规范一起发布.该版本在前一版本(Servlet 2.5)的基础上提供了若干新特性用于简化 Web 应用的开发和部署.其中有几项特性的引入让开发者感到非常兴奋,同时也获得了 Java 社区的一片赞誉之声: 异步处理支持:有了该特性,Servlet 线程不再需要一直阻塞,直到业务处理完毕才能再输出响应,最后才结束该 Servlet 线程.在接收到请求之后,Servlet 线

C# 7.0 新特性3: 模式匹配

本文参考Roslyn项目Issue:#206,及Docs:#patterns. 1. C# 7.0 新特性1: 基于Tuple的“多”返回值方法 2. C# 7.0 新特性2: 本地方法 3. C# 7.0 新特性3: 模式匹配 模式匹配也许能算的上C#本次更新最重量级的升级,也是最受关注的特性(也许没有之一),通过模式匹配,我们可以简化大量的条件代码. Switch语句 大家也许遇到过这样的情景,假设你的代码中,有一个Nullable<int>的值,需要对其在正整数,非正整数,Null三种情

C# 2.0 新特性(上)

C# 2.0新特性 1. 泛型 1.1 泛型介绍 泛型类和泛型方法同时具备可重用性.类型安全和效率,这是非泛型类和非泛型方法无法具备的.泛型通常用在集合和在集合上运行的方法中..NET Framework 2.0 版类库提供一个新的命名空间 System.Collections.Generic,其中包含几个新的基于泛型的集合类.建议面向 2.0 版的所有应用程序都使用新的泛型集合类,而不要使用旧的非泛型集合类,如 ArrayList.有关更多信息,请参见 .NET Framework 类库中的泛

atitit.j2ee 1.5 1.6 的不同跟 Servlet 3.0新特性总结

atitit.j2ee 1.5 1.6 的不同跟 Servlet 3.0新特性总结 1. jar比较,j2ee 1.6 添加了许多的jar 1 2. ,Servlet 3.0 2 2.1. 可插性  web片段 2 2.2. 异步处理 3 2.3. anno支持filter,sevlet,listen 3 2.4. 三.元数据和通用注释 3 2.5. 现有API的改进 HttpServletRequest,,HttpServletRequest,,ServletContext,,dynac fi

[转]Servlet 3.0 新特性详解

原文地址:http://blog.csdn.net/xiazdong/article/details/7208316 Servlet 3.0 新特性概览 1.Servlet.Filter.Listener无需在web.xml中进行配置,可以通过Annotation进行配置: 2.模块化编程,即将各个Servlet模块化,将配置文件也分开配置. 3.Servlet异步处理,应对复杂业务处理: 4.异步Listener,对于异步处理的创建.完成等进行监听: 5. 文件上传API简化: tomcat