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 ...
随机推荐
- 玲珑杯”ACM比赛 Round #19 B 维护单调栈
1149 - Buildings Time Limit:2s Memory Limit:128MByte Submissions:588Solved:151 DESCRIPTION There are ...
- springboot读取自己定义的配置文件的方式以及使用joda_time来处理时间日期
总的来说呢,有两种方式,一种是原始的方式,即使用PropertiesUtils来读取配置文件. 第二种就是使用springboot的注解的方式来读取配置文件. 1.原始方式处理属性和时间日期: 工具类 ...
- [linux]linuxI/O测试的方法之dd
参考http://www.thomas-krenn.com/en/wiki/Linux_I/O_Performance_Tests_using_dd Measuring Write Performan ...
- Redis 为什么用跳表而不用平衡树
Redis 为什么用跳表而不用平衡树? 本文是<Redis内部数据结构详解>系列的第六篇.在本文中,我们围绕一个Redis的内部数据结构--skiplist展开讨论. Redis里面使用s ...
- window.location.hash在firefox下中文自动转码为UTF-8问题
1.window.location.hash window.location.hash这个属性主要是读取和写入网页位置的,我们经常会用来控制网页单页面跳转或者是控制网页位置.然而这个属性在firefo ...
- myeclipse注册机,自己生成注册码
话不多少,直接上代码 直接可以运行,自己输入key即可 package com.generate.myeclipse.code; import java.io.BufferedReader; impo ...
- 前端PHP入门-019-内置函数之数学函数-很重要
查看帮助文档为主 函数名 描述 实例 输入 输出 abs() 求绝对值 $abs = abs(-4.2); //4.2 数字 绝对值数字 ceil() 进一法取整 echo ceil(9.999); ...
- TypeError: only integer scalar arrays can be converted to a scalar index
TypeError: only integer scalar arrays can be converted to a scalar index 觉得有用的话,欢迎一起讨论相互学习~Follow Me ...
- centos7下安装配置jenkins+git+maven+jdk
环境 centos7 jdk1.8 maven3 git 在安装jenkins之前,先安装jdk1.8.maven.git 一. 安装jdk1.8 第一步:下载 jdk-8u131-linux-x64 ...
- 【机器学习】K-邻近算法的python 实现
#!/usr/bin/python # -*- coding: utf-8 -*- from numpy import * import operator def createDataSet(): ' ...