F#区分C#中的Union用法 [英] 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#中的Union用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!