【问题标题】:What is a (proposed) “Record” class in C# 6?什么是 C# 6 中的(提议的)“记录”类?
【发布时间】:2014-08-20 09:08:11
【问题描述】:

我相信这从未进入 C# 6k,但可能会考虑在以后的版本中发布。

我刚刚阅读了一篇very confusing blog,其中讨论了 C# 6 中的模式匹配和记录类以及运算符“is”。

请有人给我一个关于这一切的概述,这样我就可以理解它会对我在 C# 6 发布后编写的 C# 代码产生什么影响。

(请注意,这与数据库无关!但 Google 认为确实如此……)


在找到Easier Immutable Objects in C# 6 and VB 12 之前,我先阅读Pattern Matching in C# 6 and VB 12 - 以其他顺序阅读它们会更有意义。

如果 Record 类解决了:

目前大多数 ORM 和序列化程序不支持不可变 类型。相反,他们假设会有一个无参数的构造函数 和可变属性。

通过标准化不可变类型的创建方式来解决问题,然后我可以看到它们无论模式匹配如何都很棒。

【问题讨论】:

  • 请链接到博文,否则很难得到任何上下文。
  • Various links here,但不确定哪个是来源。就我个人而言,我非常喜欢 Instapaper 的所有外观 :-)
  • infoq.com/news/2014/08/Pattern-Matching 是博客文章,但我认为它可能没有抓住重点
  • 这并没有那么令人困惑。令人困惑的是整理初级开发人员将尝试编写的杂乱的递归类型模式。

标签: c# c#-6.0


【解决方案1】:

来自here

这本质上是一个不可变的类,仅由其定义 构造函数。这是规范中的一个示例:

public record class Cartesian(double x: X, double y: Y);

除了构造函数,编译器会自动 创建:

  • 每个参数的只读属性
  • Equals 函数
  • GetHashCode 覆盖
  • ToString 覆盖
  • “is”运算符,在 VB 中称为“Matches”

我刚刚读到这个PROPOSAL: Records, and Plain Old CLR Objects

想象一下一种叫做“记录”的东西,一种具有有序列表的类型 命名数据成员。不是说应该有一种新的类型 与类和结构一起称为“记录类型”......确实如此 最好不要有一种新的类型,因为我们可能想要 类似记录的类和结构。

提议 1: 可以使用主构造函数语法定义记录,它是扩展形式的语法糖,如下所示...

class Point(int X, int Y);

==>

class Point(int X, int Y)
{
   public int X { get; } = X;
   public int Y { get; } = Y;
}

规则是:“当您编写记录时,它会自动生成 PRIMARY PROPERTIES 的属性,除非您自己提供了这些属性”。术语“主要属性”是指主要构造函数语法中的参数。因此,如果您不希望它自动生成属性,则必须提供您自己的该属性版本,如下例所示。 (没有办法用这种语法说您不想要该属性:如果您不想要该属性,则根本不要使用该功能。

class Point(int X, int Y) { public int X => 15; }

==>

class Point(int X, int Y)
{
   public int X => 15;
   public int Y {get; set;} = Y;
}

【讨论】:

  • 现在只需注意 C# 语言团队避免使用/实现实际的“记录”关键字。我在 GitHub 页面上看到的所有内容都使用已经实现的语法显示它们,它基本上看起来像一个类声明。也许如果我们幸运的话,团队中的某个人实际上会意识到存在并尝试为此功能添加适当的“记录”关键字。
【解决方案2】:

根据this discussion,这是编译器生成不可变类型(classstruct)的一种方式,可用于模式匹配和记录语义。

编译器将生成一个is 运算符用于模式匹配和EqualsGetHashCodeToString 具有记录语义的方法。

【讨论】:

  • 只是一些没有实际用例的语法糖:p
  • @Jay,你真的认为团队有那么多时间可以玩吗?
  • 我不知道,主要的构造函数和所有人都只能想知道!
【解决方案3】:

在我看来,这只会增加一些语法糖,在一些非常小众的情况下,你不应该更改旧代码,如果场景到来并有助于你的范例,你应该采用它,否则它就在那里。

这类似于异常过滤器,并且需要能够在 C# 中实现 F# 模式。

让我们考虑 'is' 重载,此构造允许编译器进行特殊过滤,但与简单地自己过滤子句相比,它的性能并不高。

例如

'if (x is Something) return (x as Something).Value > 0'

变成类似

'x 是(某事,1)'

任何人都没有意识到的问题是,当 x 通过继承或接口的其他东西的优点而成为某物时,并且这些属性是虚拟的,这可能很难调试,尤其是当每种类型都可能具有 im 隐式或显式强制转换重载时为了某件事。

此外,“记录”概念与具有底层类型的匿名类型没有什么不同。

例如某事的记录只是提供了一个围绕记录的包装器,其中您的属性是不可变的和哈希码。 (这次只是再次作为语法糖来支持具有另一组陷阱的主构造函数,例如,当继承类型定义由派生类型生成的属性时,会发生隐藏,并且您最终不得不输入所有内容)

希望能回答这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-26
    • 2014-11-29
    • 1970-01-01
    • 2010-11-18
    • 1970-01-01
    • 2022-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多