C# 6.0 新特性 (二)
自动属性初始化表达式
有过正确实现结构经验的所有 .NET 开发人员无疑都为一个问题所困扰:需要使用多少语法才能使类型固定不变(为 .NET 标准建议的类型)。此问题实际上是只读属性存在的问题:
- 定义为只读的支持字段
- 构造函数内支持字段的初始化
- 属性的显式实现(而非使用自动属性)
- 返回支持字段的显式 getter 实现
所有这一切仅仅是为了“正确地”实现固定不变的属性。之后,此情况还会针对类型的所有属性重复发生。因此,正确操作需要比不堪一击的方法付出明显更多的努力。发布了自动属性初始化表达式(CTP3 还包括对初始化表达式的支持)这个新功能后,C# 6.0 就可派上用场了。自动属性初始化表达式允许直接在属性的声明内分配属性。对于只读属性,它负责确保属性固定不变所需的所有繁琐程序。例如,请看本示例中的 FingerPrint 类:
public class FingerPrint
{
public DateTime TimeStamp { get; } = DateTime.UtcNow;
public string User { get; } =
System.Security.Principal.WindowsPrincipal.Current.Identity.Name;
public string Process { get; } =
System.Diagnostics.Process.GetCurrentProcess().ProcessName;
}
如代码所示,属性初始化表达式允许向属性分配一个初始值作为属性声明的一部分。属性可以是只读的(只包含 getter),也可以是读/写(包含 setter 和 getter)的。如果是只读的,则基础支持字段将通过只读修饰符自动声明。这就确保了在初始化之后会固定不变。
初始化表达式可以是任意表达式。例如,通过使用条件运算符,您可以设置默认初始化值:
public string Config { get; } = string.IsNullOrWhiteSpace(
string connectionString =
(string)Properties.Settings.Default.Context?["connectionString"])?
connectionString : "<none>";
本示例中,请注意之前的文章中所讨论的如何使用声明表达式(请参阅 itl.tc/?p=4040)。如果您需要的不只是表达式,可以将初始化重构到静态方法中,然后对其进行调用。
Nameof 表达式
CTP3 版本中介绍的另一个新增功能是支持 nameof 表达式。您将多次需要在代码中使用“魔幻字符串”。此类“魔幻字符串”是映射到您代码中的程序元素的普通 C# 字符串。例如,引发 ArgumentNullException 时,使用一个字符串表示无效对应参数的名称。遗憾的是,这些魔幻字符串未经过编译时验证,任意程序元素更改(例如,重命名参数)都不会自动更新魔幻字符串,从而导致不一致,而编译器根本不会发现此问题。
在其他情况下,例如引发 OnPropertyChanged 事件时,可以通过提取名称的树表达式技术避免出现魔幻字符串。鉴于操作简单(只识别程序元素名称),所以这或许有点让人头疼。无论哪种情况,解决方案都不太理想。
若要解决这一特性,C# 6.0 提供了对“程序元素”名称的访问权限,无论是类名称、方法名称、参数名称还是特定属性名称(可能是对于使用反射的情况)。例如,图 2 中的代码使用 nameof 表达式提取参数的名称。
//使用 Nameof 表达式提取参数名称 void ThrowArgumentNullExceptionUsingNameOf(string param1)
{
throw new ArgumentNullException(nameof(param1));
}
[TestMethod]
public void NameOf_UsingNameofExpressionInArgumentNullException()
{
try
{
ThrowArgumentNullExceptionUsingNameOf("data");
Assert.Fail("This code should not be reached");
}
catch (ArgumentNullException exception)
{
Assert.AreEqual<string>("param1", exception.ParamName);
}
正如测试方法所演示的,ArgumentNullException 的 ParamName 属性具有 param1 值,这是使用方法中的 nameof(param1) 表达式的值集。Nameof 表达式不仅仅用于参数,您还可以使用它来检索所有编程元素。
//检索其他编程元素 namespace CSharp6.Tests
{
[TestClass]
public class NameofTests
{
[TestMethod]
public void Nameof_ExtractsName()
{
Assert.AreEqual<string>("NameofTests", nameof(NameofTests));
Assert.AreEqual<string>("TestMethodAttribute",
nameof(TestMethodAttribute));
Assert.AreEqual<string>("TestMethodAttribute",
nameof(
Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute));
Assert.AreEqual<string>("Nameof_ExtractsName",
string.Format("{0}", nameof(Nameof_ExtractsName)));
Assert.AreEqual<string>("Nameof_ExtractsName",
string.Format("{0}", nameof(
CSharp6.Tests.NameofTests.Nameof_ExtractsName)));
}
}
}
Nameof 表达式仅检索最终的标识符,即使您使用更多的显式包含点的名称也是如此。此外,对于属性而言,未隐含“Attribute”后缀。相反,编译需要它。它非常适合用于清理混乱代码。
原文出处:http://msdn.microsoft.com/zh-cn/magazine/dn802602.aspx
C# 6.0 新特性 (二)的更多相关文章
- C++2.0新特性(二)——<一致性初始化、Initializer_list 、for循环、explicit>
一.一致性初始化(uniform initialization) 之前初始化时存在多个版本,让使用者使用时比较混乱,现在提供一种万用的初始化方法,就是使用大括号. 原理解析:当编译器看到大括号包起来的 ...
- c# 6.0新特性(二)
写在前面 上篇文章介绍了c#6.0的using static,Auto Property Initializers,Index Initializers新的特性,这篇文章将把剩下的几个学习一下. 原文 ...
- 浅谈Tuple之C#4.0新特性那些事儿你还记得多少?
来源:微信公众号CodeL 今天给大家分享的内容基于前几天收到的一条留言信息,留言内容是这样的: 看了这位网友的留言相信有不少刚接触开发的童鞋们也会有同样的困惑,除了用新建类作为桥梁之外还有什么好的办 ...
- C#发展历程以及C#6.0新特性
一.C#发展历程 下图是自己整理列出了C#每次重要更新的时间及增加的新特性,对于了解C#这些年的发展历程,对C#的认识更加全面,是有帮助的. 二.C#6.0新特性 1.字符串插值 (String In ...
- [转]Servlet 3.0 新特性详解
原文地址:http://blog.csdn.net/xiazdong/article/details/7208316 Servlet 3.0 新特性概览 1.Servlet.Filter.Listen ...
- [C#]6.0新特性浅谈
原文:[C#]6.0新特性浅谈 C#6.0出来也有很长一段时间了,虽然新的特性和语法趋于稳定,但是对于大多数程序猿来说,想在工作中用上C#6.0估计还得等上不短的一段时间.所以现在再来聊一聊新版本带来 ...
- 腾讯云安全:开发者必看|Android 8.0 新特性及开发指南
欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 背景介绍 谷歌2017 I/O开发者大会今年将于5月17-19日在美国加州举办.大会将跟往年一样发布最新的 A ...
- Android Oreo 8.0 新特性实战 Autosizing TextView --自动缩放TextView
Android Oreo 8.0 新特性实战 Autosizing TextView --自动缩放TextView 8.0出来很久了,这个新特性已经用了很久了,但是一直没有亲自去试试.这几天新的需求来 ...
- Django 2.0 新特性 抢先看!
一.Python兼容性 Django 2.0支持Python3.4.3.5和3.6.Django官方强烈推荐每个系列的最新版本. 最重要的是Django 2.0不再支持Python2! Django ...
随机推荐
- Topcoder SRM570 D1L3 CurvyonRails
几个样例: 5 5wCCwwwCC....w......www..wReturns: 0 3 3C.w....C.Returns: 1 21 20CC..CCCw.CwC..CC.w.CC.CCCwC ...
- linux jq命令小结
http://note.youdao.com/noteshare?id=0d84ff04edcaa0be512eb0c1e5c41f47
- lightoj 1215
lightoj 1215 Finding LCM 链接:http://www.lightoj.com/volume_showproblem.php?problem=1215 题意:已知 a, b, l ...
- Linux常用网络工具:路由扫描之traceroute
之前两篇<Linux常用网络工具:fping主机扫描>和<Linux常用网络工具:hping高级主机扫描>都是关于主机扫描的,本篇介绍Linux下常用的路由扫描工具tracer ...
- js 30分钟倒计时
<html> <head> <meta charset="UTF-8"> <title></title> </he ...
- novaclient源码分析
源码版本:H版 FAULT_OS_COMPUTE_API_VERSION = "1.1" 一.目录结构及概况 novaclient/ |---client.py --------- ...
- HTML5增强的表单
form元素a.用来定义一个表单,是建立表单的基础元素(就类似定义表格的table)b.表单的其他元素包含在form元素中,其主要子元素有:input/button/select......form元 ...
- 还不会做! 树上的gcd 树分治 UOJ33
题目链接:http://uoj.ac/problem/33 题解链接:http://vfleaking.blog.uoj.ac/blog/38 现在感觉到了做OI的层层递进的思路的伟大之处,作为一个大 ...
- JS DOM之表格操作
一个能给添加行的表格 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type&qu ...
- 【Hadoop】大数据时代,我们为什么使用hadoop
博客已转移,请借一步说话.http://www.daniubiji.cn/archives/538 我们先来看看大数据时代, 什么叫大数据,“大”,说的并不仅是数据的“多”!不能用数据到了多少TB , ...