F# 区分联合使用与 C# [英] F# Discriminated Union usage from C#
问题描述
从 C# 中使用 F# 区分联合的最佳方法是什么?
What are the best ways to use F# Discriminated Unions from C#?
这个问题我已经研究了一段时间了,我可能找到了最简单的方法,但由于它相当复杂,可能还有一些我没有看到的东西......
I have been digging into this problem for a while, I have probably found the simplest way, but as it is rather complex, there may be some other thing I don't see...
有一个受歧视的工会,例如:
Having a discriminated union, e.g.:
type Shape =
| Rectangle of float * float
| Circle of float
我发现 C# 的用法是(避免使用 vars,使类型明显):
the usage from C# I found would be (avoiding using vars, to make the type obvious):
Shape circle = Shape.NewCircle(5.0);
if (circle.IsCircle)
{
Shape.Circle c = (Shape.Circle)circle;
double radius = c.Item;
}
在C#中,NewXXXX
静态方法总是创建Shape
类的对象,还有一个方法IsXXXX
来检查对象是否是类型;当且仅当是时,它可以转换为 Shape.XXXX
类,并且只有这样它的项目才可以访问;Shape.XXXX
类的构造函数是内部的,即不可访问.
In C#, the NewXXXX
static methods always create object of the Shape
class, there is also a method IsXXXX
to check if the object is of the type; if and only if yes, it is castable to the Shape.XXXX
class, and only then its items are accessible; constructor of the Shape.XXXX
classes are internal, i.e. unaccessible.
有没有人知道从受歧视的联合中获取数据的更简单的选择?
Is anyone aware of a simpler option to get the data from a discriminated union?
推荐答案
如果您正在用 F# 编写一个暴露给 C# 开发人员的库,那么 C# 开发人员应该能够在不了解 F#(并且不知道它是用 F# 编写的).这也是 F# 设计指南 推荐的.
If you are writing a library in F# that is exposed to C# developers, then C# developers should be able to use it without knowing anything about F# (and without knowing that it was written in F#). This is also recommended by F# design guidelines.
对于有区别的联合,这很棘手,因为它们遵循与 C# 不同的设计原则.因此,我可能会在 F# 代码中隐藏所有处理功能(如计算区域)并将其公开为普通成员.
For discriminated unions, this is tricky, because they follow different design principles than C#. So, I would probably hide all processing functionality (like calculating area) in the F# code and expose it as ordinary members.
如果您真的需要向 C# 开发人员公开这两种情况,那么我认为这样的事情对于简单的可区分联合来说是一个不错的选择:
If you really need to expose the two cases to C# developers, then I think something like this is a decent option for a simple discriminated union:
type Shape =
| Rectangle of float * float
| Circle of float
member x.TryRectangle(width:float byref, height:float byref) =
match x with
| Rectangle(w, h) -> width <- w; height <- h; true
| _ -> false
member x.TryCircle(radius:float byref) =
match x with
| Circle(r) -> radius <- r; true
| _ -> false
在C#中,你可以像熟悉的TryParse
方法一样使用它:
In C#, you can use it in the same way as the familiar TryParse
methods:
int w, h, r;
if (shape.TryRectangle(out w, out h)) {
// Code for rectangle
} else if (shape.TryCircle(out r)) {
// Code for circle
}
这篇关于F# 区分联合使用与 C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!