【发布时间】:2020-12-22 17:32:59
【问题描述】:
在 C# 中使用 record 类型,构建类似可区分联合的数据结构似乎非常有用,我只是想知道我是否遗漏了一些我会后悔的陷阱之后。例如:
abstract record CardType{
// Case types
public record MaleCardType(int age) : CardType{}
public record FemaleCardType : CardType{}
// Api
public static MaleCardType Male(int age) => new MaleCardType(age);
public static FemaleCardType Female => new FemaleCardType();
}
var w = CardType.Male(42);
var x = CardType.Male(42);
var y = CardType.Male(43);
var z = CardType.Female;
Assert.Equal<CardType>(w,x); //true
Assert.Equal<CardType>(x,y); //false
Assert.Equal<CardType>(y,z); //false
这似乎比使用单例和相等比较器以及所有这些构建抽象类要简单得多,但我是否错过了一些我不想这样做的原因?
【问题讨论】:
-
DU 允许您根据类型编写详尽的开关表达式。您可以简单地通过从同一个空接口继承不同类型来进行非穷举切换,不需要单例或抽象类。问题是穷举。 this 代码如何让您编写详尽的 switch 表达式?
-
似乎您试图复制 F# 类型的构造函数。这不是让 C# DU 工作所缺少的。事实上,如果您使用布尔属性(或编译器已知值的任何类型,如果存在这种情况),您可以获得详尽的短裤匹配。 Check this answer to a similar question.
-
谢谢@PanagiotisKanavos!我认为我的问题不在于模式匹配方面,因为无论如何这在 C# 中从来都不是一件容易的事,而是关于使用记录来完成这个数据结构而不是类。 (是的,我正在努力让 C# 像 F# 一样工作,哈哈。不幸的是,我不需要我的团队授权来推动我们使用 F#,但如果我能与 C# 足够接近,我会很高兴的! )
-
模式匹配是简单而新颖,
never been easy不适用。 DU 的问题在于广泛匹配,否则您可以执行 F# 对 C# 所做的相同操作。如果它们也那么容易,C# 团队也不会延迟它们两次。他们本可以选择 TypeScript 的功能,强迫人们打开标签,但这会使 DU 很难使用 -
感谢@PanagiotisKanavos,感谢您的 cmets。
标签: oop enums discriminated-union c#-9.0 record-classes