Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么可以';我是否使用扩展方法隐式强制转换委托?_C#_Functional Programming_Extension Methods_Currying - Fatal编程技术网

C# 为什么可以';我是否使用扩展方法隐式强制转换委托?

C# 为什么可以';我是否使用扩展方法隐式强制转换委托?,c#,functional-programming,extension-methods,currying,C#,Functional Programming,Extension Methods,Currying,我正试图找到一种方法,自动将某些内容转换为动作或函数,我能想到的最好方法是这样: [TestFixture] public class ExecutionTest { public void BadMethod() { throw new Exception("Something bad happened"); } [Test] public void TestBadMethod() { // Want this,

我正试图找到一种方法,自动将某些内容转换为动作或函数,我能想到的最好方法是这样:

[TestFixture]
public class ExecutionTest
{
    public void BadMethod()
    {
        throw new Exception("Something bad happened");
    }

    [Test]
    public void TestBadMethod()
    {
        // Want this, but it won't work!!
        // BadMethod.Execute().IgnoreExceptions();

        // Ick
        ((Action)BadMethod).Exec().IgnoreExceptions();

        // Still ick
        ((Action)BadMethod).IgnoreExceptions();

        // Do not want
        ExtensionMethods.Exec(BadMethod).IgnoreExceptions();

        // Better but still meh
        this.Exec(BadMethod).IgnoreExceptions();

    }
}

public static class ExtensionMethods
{
    public static Action Exec(this Action action)
    { return action; }

    public static Action Exec(this object obj, Action action)
    { return action; }

    public static void IgnoreExceptions(this Action action)
    {
        try { action(); }
        catch {}
    }
}
必须有更好/更简单的方法来实现这一点,有什么想法吗?

在C#中,当使用不带括号的方法名时,它被称为方法组,除了在编译时,它没有其他表示形式。一个方法组可以表示多个方法(因为重载和重写),因此为了隐式地标识需要哪个方法,必须提供一个目标委托类型

在您的例子中,您想知道为什么扩展方法参数类型不会触发函数的解析。简单地说,扩展是在已知类型后计算的,也就是说,this参数不能用作隐式转换目标

它会破裂的原因示例:

class Test
{
    void M (void) // Fits Action delegate
    {
    }

    int M (int) // Fits Func<int,int> delegate
    {
        return 5;
    }

    void Test()
    {
        M.Exec(); // UHOH!!! Which Exec to resolve to ???
    }
}


public static class Extensions
{
    public static void Exec(this Action action) { }
    public static void Exec(this Func<int, int> func) { }
}

C#无法将
A
C.Blah(int)
匹配,因为它需要隐式转换。

正如Coincoin所说,它在C#中无法很好地工作,因为它过于热衷于方法重载。我看到人们使用的唯一解决方法是创建Action和Func方法:

public Action Action(Action f) { return f; }
public Action<A> Action<A>(Action<A> f) { return f; }
...
public Func<A,B,C,D,E> Func(Func<A,B,C,D,E> f) { return f; }
您可能决定不在类中定义这些方法,而是将它们放在Funcs实用工具或其他东西中。将其别名为F,结果不会太糟糕:

F.F(BadMethod).NoException();

但总的来说,它仍然很糟糕:(.

F#通过提供更好的类型推断系统,让您非常自然地完成这类事情。

不确定这是否是方法重载的问题,因为编译器会找出要调用的方法。但这是我迄今为止看到的最好答案……是的,这就是为什么我有扩展方法(这个对象,Action-Action)所以它可以通过调用this.Action()或this.Func()在任何类中工作抱歉,我没有看到Exec定义——有点误导性的名称,没有:PYeah,我在实际代码中重命名了它。当时它看起来“流畅”。
F(BadMethod).NoExceptions();
F.F(BadMethod).NoException();