c# - 从 C# 调用 F# 时,OO 替代 F# 中的多态性

标签 c# oop f#

我想创建一个库,它将使用用户定义的函数创建对象并使用另一个用户定义的函数修改它们。

我有 OCaml 背景并且看到了一种相当简单的实现方法:

//user side
type userType = { mutable time : float }

let userInitialization () = { time = 0. }    
let userModification t = t.time <- t.time+1.

//my side
let algo initialization modification n =
    let a = Array.init n (fun _ -> initialization ())
    modification a.[0]
    a

问题是我希望该库易于从 C# 调用:将函数作为参数可能不是一个好主意。

接口(interface)和抽象类(将由 userType 继承)似乎是通常的 OO 解决方案,但如果我不知道(尚未定义)userType,我将无法初始化对象初始化步骤,在我的函数中,是不可能的。

我能想到的唯一解决方法是要求用户提供他的 userType 实例作为用于调用初始化的参数,但这似乎很不雅观。

有没有办法解决这个问题?

最佳答案

你可以这样定义一个接口(interface):

type IInitAndModify<'T> =
    abstract member CreateNew : unit -> 'T
    abstract member Modify : item : 'T -> unit

也许还有一个对象,用户可以用来将它传递给您的实现:

type Algo<'T> () =
    member this.Execute (initAndModify : IInitAndModify<'T>, n) =
        algo initAndModify.CreateNew initAndModify.Modify n

在 C# 中,它看起来像这样:

public interface IInitAndModify<T>
{
    T CreateNew();
    void Modify(T item);
}

public class Algo<T>
{
    public Algo();

    public T[] Execute(IInitAndModify<T> initAndModify, int n);
}

客户端开发人员可以像这样使用它:

public class UserType
{
    public float Time { get; set; }
}

public class UserInitAndModify : IInitAndModify<UserType>
{
    public UserType CreateNew()
    {
        return new UserType { Time = 0 };
    }

    public void Modify(UserType item)
    {
        item.Time++;
    }
}

然后写一个这样的程序:

static void Main(string[] args)
{
    var a = new Algo<UserType>();
    var values = a.Execute(new UserInitAndModify(), 10);
    foreach (var v in values)
        Console.WriteLine(v.Time);
}

当运行上面的Main方法时,输出是这样的:

1
0
0
0
0
0
0
0
0
0
Press any key to continue . . .

关于c# - 从 C# 调用 F# 时,OO 替代 F# 中的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37628624/

相关文章:

c# - OpenFileDialog 在显示浏览对话框之前抛出 System.IO.FileNotFoundException

c# - IUnknown 接口(interface) - 对于 COM\COM + 对象?

ruby-on-rails - 在 Rails 中,对象是否应该仅限于具有 View 和 Controller 的对象?

error-handling - "Merging"F# 中的歧视联合?

f# - 为什么 [2..3..10] 会被解释为 [2;5;8]

f#链表实现记录

c# - 我如何在 Revit 2017 中获得房间分隔符

c# - db4o 查询 : find all objects with ID = {anything in array}

c++ - 这是合法/安全的 C++ 吗? (向下转换为相同大小的继承类)

javascript - 将函数传递给属性