This question already has answers here:
What is the simplest way to access data of an F# discriminated union type in C#?

(7个答案)


6年前关闭。




使用C#中的F#区分联盟的最佳方法是什么?

我研究这个问题已有一段时间了,我可能已经找到了最简单的方法,但是由于它相当复杂,所以可能还有其他我看不到的东西。

有歧视的工会,例如:

type Shape =
    | Rectangle of float * float
    | Circle of float

我发现的C#的用法是(避免使用vars,以使类型显而易见):
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类的构造函数是内部的,即无法访问。

有谁知道从受歧视的联合会获取数据的更简单选择?

最佳答案

如果您要使用F#编写向C#开发人员公开的库,那么C#开发人员应该可以在不了解F#的情况下使用它(并且不知道它是用F#编写的)。 F# design guidelines也建议这样做。

对于有区别的工会,这很棘手,因为它们遵循与C#不同的设计原则。因此,我可能会在F#代码中隐藏所有处理功能(例如计算区域),并将其公开为普通成员。

如果您确实需要向C#开发人员公开这两种情况,那么我认为对于简单的有区别的联合来说,这样的选择是不错的选择:

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方法相同的方式使用它:
int w, h, r;
if (shape.TryRectangle(out w, out h)) {
  // Code for rectangle
} else if (shape.TryCircle(out r)) {
  // Code for circle
}

关于c# - F#从C#中区分出联盟用法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23843142/

10-17 02:14