隐式转换为Func

7
假设我有一个接口IMyInterface<T>,它只描述一个函数:
public interface IMyInterface<T>
{
    T MyFunction(T item);
}

我可以使用 Func<T, T> 来替代这个接口,但出于语义原因,我希望保留这个接口。我能否定义一个隐式转换,将该接口和 Func<T,T> 相互转换,以便我可以像使用 Func<T,T> 一样将匿名委托或 Lambda 表达式作为参数传递给接受此接口作为参数的函数?
为了演示,使用上面声明的接口,我想要一个类似于以下函数的函数:
public T TestFunction<T>(IMyInterface myInterface, T value)
{
    return myInterface.MyFunction(value);
}

我可以像这样调用:

TestFunction(x => x + " world", "hello");

结果会是“hello world”。


1
你是不是想在第二个代码块中调用IMyInterface.MyFunction()函数? - Andy
1个回答

4
由于C#中的接口不能包含运算符的定义(或任何静态方法),因此我认为答案是否定的。另一种选择是使用类(不幸的是不能是抽象类,因为静态成员/运算符在这里表现得并不比接口好)。这将允许您定义隐式转换运算符,因此能够按照您指定的方式精确地使用该类型。 在该类中(如果需要,您可以使其虚拟),您将定义如下内容。
public class MyClass<T>
{
    public static implicit operator MyClass<T>(Func<T, T> func)
    {
        return new MyClass<T>() { MyFunction = func };
    }

    public MyClass()
    {
    }

    public Func<T, T> MyFunction
    {
        get;
        set;
    }
}

您在问题中对于TestFunction的定义应该与您编写的代码完全一致。
public T TestFunction<T>(IMyInterface myInterface, T value)
{
    return myInterface.MyFunction(value);
}

同样地,对于TestFunction的调用:

TestFunction<string>(x => return x + " world", "hello");

这可能不是你想要的精确内容,但它仍然相当接近,而且很可能是你能得到的最好的。


TestFunction 如何将 lambda 转换为 IMyInterface 接口?你定义了一个类 MyClass,而不是接口。我认为还需要进行一些编辑... - Daniel Earwicker
@Earwicker:仔细看一下——隐式转换运算符应该为您完成这项工作,除非我弄错了。此外,如果您阅读我的帖子开头,我提到它不可能使用接口,只能使用(非抽象)类。 - Noldorin
这基本上是我预期的,但我以前也有可能会忽略一些东西,并希望这次也是这种情况。可悲的是,事实并非如此。事实上,我已经有了自己的具体实现,与您发布的内容非常相似。 - Joel Coehoorn
是的,任何“更好”的东西都需要支持静态接口,不幸的是这并不存在(也许在未来的C#版本中会有这个功能?)。至少从设计上看,我们已经实现了非常相似的实现,这是一个积极的迹象。 :) - Noldorin
我知道已经有一段时间了,但是在你的“TestFunction”定义中,“IMyInterface”的定义是什么?你的代码无法工作,因为在用户定义的转换之前只能发生标准的隐式转换,而从lambda(或匿名方法)到委托的转换不是其中之一(请参见规范6.3.1)。 (另外,在没有大括号的lambda中使用return是非法的。) - NetMage
为什么你说你不能用抽象类来实现它?如果以前做不到,现在你可以了。 - Dave Cousineau

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