Oop 使用C#9.0记录构建类似枚举/区分并集/求和类型的智能数据结构?

Oop 使用C#9.0记录构建类似枚举/区分并集/求和类型的智能数据结构?,oop,enums,discriminated-union,c#-9.0,record-classes,Oop,Enums,Discriminated Union,C# 9.0,Record Classes,在C#中使用记录类型,构建有区别的并集式数据结构似乎非常有用,我只是想知道我是否遗漏了一些以后会后悔的问题。例如: 抽象记录卡片类型{ //案例类型 公共记录MaleCardType(int age):CardType{} 公共记录FemaleCardType:CardType{} //原料药 公共静态MaleCardType Male(int age)=>新MaleCardType(age); 公共静态FemaleCardType女性=>新FemaleCardType(); } var w=卡

在C#中使用
记录
类型,构建有区别的并集式数据结构似乎非常有用,我只是想知道我是否遗漏了一些以后会后悔的问题。例如:

抽象记录卡片类型{
//案例类型
公共记录MaleCardType(int age):CardType{}
公共记录FemaleCardType:CardType{}
//原料药
公共静态MaleCardType Male(int age)=>新MaleCardType(age);
公共静态FemaleCardType女性=>新FemaleCardType();
}
var w=卡片类型。男性(42);
var x=卡片类型。男性(42);
变量y=卡片类型。男性(43);
var z=卡片类型。女性;
断言相等(w,x)//真的
断言相等(x,y)//假的
断言相等(y,z)//假的

这似乎比用单例和相等比较器等构建抽象类要简单得多,但我是否缺少了一些不想这样做的原因?

这是一个很好的方法,我一直在使用它,例如,它有一些C代码示例,一些使用类型和区分并集的F代码示例,然后是一些修改过的(但仍然很糟糕的C代码)。所以我用C#9s记录和做DU的相同方法重写了C#9s记录

示例代码比F#代码略显丑陋,但仍然非常简洁,并具有F#代码的优点

使用系统;
使用System.Collections.Immutable;
名称空间控制台
{
记录项目(字符串值);
记录付款(十进制金额);
摘要记录车
{
公共记录为空():购物车
{
public new static Active Add(CartItem项)=>new(ImmutableList.Create(item));
}
活动公共记录(不可变列表未付费项目):购物车
{
public-new-Active-Add(CartItem-item)=>this和{UnpaidItems=UnpaidItems.Add(item)};
公共新购物车删除(CartItem item)=>使用{UnpaidItems=UnpaidItems.Remove(item)}开关执行此操作
{
var(items)when items.IsEmpty=>new Empty(),
{}active=>active
};
公共新购物车付款(十进制金额)=>新付款(未付款项目,新(金额));
}
公共记录PaidFor(不可变列表PaidItems,付款):购物车;
公共购物车展示()
{
Console.WriteLine(此开关
{
Empty=>“购物车是空的”,
活动购物车=>$“购物车有{cart.UnpaidItems.Count}个商品”,
PaidFor(var项目,var付款)=>$“购物车有{items.Count}个已付款项目。已付款金额:{payment.Amount}”,
_=>“未知”
});
归还这个;
}
公共购物车添加(CartItem项目)=>此开关
{
Empty=>Empty.Add(项目),
活动状态=>state.Add(项),
_=>这个
};
公共静态购物车NewCart=>newempty();
公共购物车删除(CartItem项目)=>此开关
{
活动状态=>状态。删除(项目),
_=>这个
};
公共购物车付款(十进制金额)=>此开关
{
活动购物车=>购物车付款(金额),
_=>这个
};
}
班级计划
{
静态void Main(字符串[]参数)
{
购物车
.Display()
.添加(新的(“苹果”))
.添加(新的(“橙色”))
.Display()
.移除(新的(“橙色”))
.Display()
.移除(新的(“苹果”))
.Display()
.添加(新的(“橙色”))
.薪酬(2300万)
.Display();
;
}
}
}

DUs允许您根据类型编写详尽的开关表达式。只需让不同类型从同一个空接口继承,就可以实现非穷举切换,不需要单例或抽象类。问题是太多了。这段代码如何允许您编写一个详尽的开关表达式?似乎您试图复制一个F#types构造函数。这不是让C#du工作所缺少的。事实上,如果您使用布尔属性(或者编译器已知值的任何类型,如果存在这样的情况),您可以获得短裤的完全匹配。谢谢,@PanagiotisKanavos!我想我的问题不在模式匹配方面,因为这在C#中从来都不是一件容易的事,而是如何使用记录来完成这种数据结构,而不是类。(是的,我正试图让C像F一样工作,哈。不幸的是,我不需要授权我的团队让我们使用F,但如果我能与C足够接近,我会很高兴!)模式匹配很容易,而且非常新,以至于
从来都不容易
不适用。但是DU的问题是广泛的匹配,否则您可以像F#处理C#一样处理。如果C#团队也这么容易的话,他们也不会两次拖延。他们本可以选择TypeScript的功能,强迫人们打开标签,但这会让DU很难使用谢谢@PanagiotisKanavos,我感谢你的评论。