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();