我想创建一个库,它将使用用户定义的函数创建对象并使用另一个用户定义的函数修改它们。
我有 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/