在C#中实现返回Unit类型的F#接口成员

5
假设我在F#中定义了以下接口:

Suppose I've defined the following interface in F#:

type IFoo<'T> = 
  abstract member DoStuff : 'T -> unit

如果我在C#中实现这个,方法签名应该是:

public void DoStuff<T>(T arg) {...}

我真正想要做的是引用 FSharp.Core,然后使用:

public Unit DoStuff<T>(T arg) {...}

这将简化其他代码,因为我不必处理Action和Func之间的区别。我猜想没有任何干净的方法可以实现这一点?用一些邪恶的黑客手段呢?

你宁愿从C#处理令人讨厌的FSharpFuncs和不熟悉的C#开发者吗?你可能可以实现自己的“Unit”类型并使用它,但这真的是一个可怕的想法。 - Robert Jeppesen
2
以上内容均不需要在C#中使用FSharpFuncs。不熟悉这个问题只有通过熟悉才能解决。我同意自己的Unit类型是一个可怕的想法:RX已经引入了自己的版本;世界上不需要另一个 :) - Akash
1个回答

6
Unit 转换为 void 是编译器内置的。在 F# 核心库中有一个 FuncConvert 类用于在 FSharpFuncConverter 之间进行转换。那么是否可以定义一个类似的类,将 Action<T> 转换为 Func<T, Unit>
static class ActionConvert {
    private static readonly Unit Unit = MakeUnit();

    public static Func<T, Unit> ToFunc<T>(Action<T> action) {
        return new Func<T, Unit>(x => { action(x); return Unit; });
    }

    private static Unit MakeUnit() {
        //using reflection because ctor is internal
        return (Unit)Activator.CreateInstance(typeof(Unit), true);
    }
}

那么你可以这样做:

然后,您可以这样做

var foo = new Foo<int>();
var func = ActionConvert.ToFunc<int>(foo.DoStuff);

您甚至可以放弃Unit实例,而返回null


可以了,谢谢!但我仍希望我们在实现接口时能选择使用Unit。我发现自己在其他地方也在使用它。 - Akash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接