隐式转换为Func或Action委托?

6
C#允许你定义一个隐式转换为委托类型:
class myclass
{
    public static implicit operator Func<String, int>(myclass x)
    {
        return s => 5;
    }
    public static implicit operator myclass(Func<String, int> f)
    {
        return new myclass();
    }
}

但不幸的是,我们不能使用这种方法让一个对象看起来像一个函数:

var xx = new myclass();
int j = xx("foo");    // error
Action<Func<String, int>> foo = arg => { };
foo(xx);              // ok

有没有一种好的方法让自己类的对象直接在其基础实例上接受函数式参数(参数)?有点像索引器,但是使用圆括号而不是方括号?


1
我真的希望没有这样的情况发生。这会导致代码非常难以阅读。 - Femaref
2
@Femaref:实际上,这在Python中被广泛使用,并且取得了很好的效果。 - Cameron
2
糟糕的面向对象设计,但如果你必须这样做,你可以使用所需参数的索引器。如果它看起来很丑陋,那么你最好使用“[”而不是“(”。 - SimpleVar
@Femaref 我来晚了,但这简直不是真的。在代码中有很多情况下,将函数视为一等对象和函数本身都是很好的选择。例如类型回调(这种语言已经支持将函数作为一等对象,但这也加强了这个观点;这些实际上是在一等对象之上可调用的对象/函数的静态扩展)。 - gabriel.hayes
1个回答

4
不,C#语言本身并不允许这样做。CLI在底层使用callcallvirt指令来调用方法或者通过委托间接调用方法。因此,与Python不同的是,在C#中不存在类似的特性,即无法通过声明def __call__方法来使类实例成为可调用对象。

谢谢回复。在标记答案之前,我会再等一段时间,看看是否有任何不常见的解决方法。 - Glenn Slayden
截至C# 6,这仍然是这种情况吗? - TKharaishvili
2
@GwynBleidd 是的,CLI 已经有一些变化了,但是核心概念是不能改变的,正如回复中所提到的。此外,我不认为我们会在 C# 中看到这个功能。 - Tomasz Juszczak
截至C# 7.1,这仍然是现状吗? - shtse8
@shtse8 是的。并且8。并且9。并且10... - Glenn Slayden

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