.NET Framework - C# 7.0 中的新增功能

解构函数

从 C# 1.0 开始,就能调用函数,就是将参数组合起来并封装到一个类中的构造函数。但是,从来没有一种简便的方式可将对象解构回其各个组成部分。例如,假设有一个 PathInfo 类,它采用文件名的每个元素(目录名、文件名、扩展名),并将它们组合成一个对象,然后支持操作对象的不同元素。现在,假设你需要将该对象提取(解构)回其各个组成部分。

在 C# 7.0 中,通过解构函数完成这项任务将变得轻而易举,解构函数可返回对象的具体确定组件。注意,不要将解构函数 (deconstructor) 与析构函数 (destructor)(确定性对象解除分配和清除)或终结器 (itl.tc/CSharpFinalizers) 混淆。

我们来看看图 1 中的 PathInfo 类。

1 具有解构函数的 PathInfo 类及相关测试
public class PathInfo
{
  public string DirectoryName { get; }
  public string FileName { get; }
  public string Extension { get; }
  public string Path
  {
    get
    {
      return System.IO.Path.Combine(
        DirectoryName, FileName, Extension);
    }
  }
  public PathInfo(string path)
  {
    DirectoryName = System.IO.Path.GetDirectoryName(path);
    FileName = System.IO.Path.GetFileNameWithoutExtension(path);
    Extension = System.IO.Path.GetExtension(path);
  }
  public void Deconstruct(
    out string directoryName, out string fileName, out string extension)
  {
    directoryName = DirectoryName;
    fileName = FileName;
    extension = Extension;
  }
  // ...
}

显然,可以和在 C# 1.0 一样调用 Deconstruct 方法。但是,C# 7.0 提供了可以显著简化调用的语法糖。如果存在解构函数的声明,则可以使用新的 C# 7.0“类似元组”的语法调用它(参见图 2)。

2 解构函数调用和赋值
PathInfo pathInfo = new PathInfo(@"\\test\unc\path\to\something.ext");
{
  // Example 1: Deconstructing declaration and assignment.
  (string directoryName, string fileName, string extension) = pathInfo;
  VerifyExpectedValue(directoryName, fileName, extension);
}
{
  string directoryName, fileName, extension = null;
  // Example 2: Deconstructing assignment.
  (directoryName, fileName, extension) = pathInfo;
  VerifyExpectedValue(directoryName, fileName, extension);
}
{
  // Example 3: Deconstructing declaration and assignment with var.
  var (directoryName, fileName, extension) = pathInfo;
  VerifyExpectedValue(directoryName, fileName, extension);
}

请注意,C# 第一次如何允许同时向不同值的多个变量赋值。这与将所有变量都初始化为同一值 (null) 的空赋值声明不同:

string directoryName, filename, extension = null;
通过新的类似元组的语法,赋予每个变量一个不同的值,该值与其名称不对应,但与它出现在声明和解构语句中的顺序相对应。

正如你所期望的,out 参数的类型必须与被分配的变量类型相匹配,并且允许使用 var,因为此类型可以从 Deconstruct 参数类型中推断出来。但是,请注意,虽然可以在圆括号外面放置一个 var(如图 2 中的示例 3 所示),但此时即使所有变量的类型均相同,也不能拉出字符串。

请注意,此时 C# 7.0 类似元组的语法要求圆括号内至少出现两个变量。例如,即使存在类似如下的解构函数,也不允许使用 (FileInfo path) = pathInfo;:

public void Deconstruct(out FileInfo file)
换句话说,不能对仅有一个 out 参数的 Deconstruct 方法使用 C# 7.0 解构函数。

使用元组

正如我所说过的,前面的每个示例都利用了 C# 7.0 类似元组的语法。此类语法的特点就是用圆括号括住分配的多个变量(或属性)。我之所以使用术语“类似元组的”,是因为所有这些解构函数示例实际上在内部均未使用任何元组类型。(实际上,由于已分配的对象是表示封装的组成部分的实例,因此,不允许通过解构函数语法分配元组,也可以说这样做不太必要。)

借助 C# 7.0,现在有了一种特别简化的语法,可以使用元组,如图 3 所示。只要允许使用类型说明符,就可以使用这种语法,其中包括声明、强制转换运算符和类型参数。

3 声明、实例化并使用 C# 7.0 元组语法
[TestMethod]
public void Constructor_CreateTuple()
{
  (string DirectoryName, string FileName, string Extension) pathData =
    (DirectoryName: @"\\test\unc\path\to",
    FileName: "something",
    Extension: ".ext");
  Assert.AreEqual<string>(
    @"\\test\unc\path\to", pathData.DirectoryName);
  Assert.AreEqual<string>(
    "something", pathData.FileName);
  Assert.AreEqual<string>(
    ".ext", pathData.Extension);
  Assert.AreEqual<(string DirectoryName, string FileName, string Extension)>(
    (DirectoryName: @"\\test\unc\path\to",
      FileName: "s
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值