我正在试图找出一种方法来自动将某些内容转换为Action或Func,而我能想出的最好的方法是这样的:
[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#中,当您使用不带括号的方法名称时,它被称为方法组,除了在编译时它没有任何表示.方法组可以表示多个方法(由于重载和覆盖),因此要隐式标识需要哪个方法,必须提供目标委托类型.
在您的情况下,您想知道为什么扩展方法参数类型不会触发函数的解析.简单地说,在已知类型之后评估扩展,即,此参数不能用作隐式转换目标.
它破裂的原因示例:
class Test { void M (void) // Fits Action delegate { } int M (int) // Fits Funcdelegate { 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 func) { } }
正如您所看到的,存在冲突,但事实上,冲突永远不会发生,因为C#甚至不会尝试使用方法组找到匹配的扩展.
请注意这不会起作用:
class A { public static implicit operator int (A a) { return 5; } void F() { A a = new A(); a.Blah(); // Error! It won't implicitly try C.Blah() } } public static class C { public static void Blah (int i) { } }
C#将不匹配A
,C.Blah(int)
因为它需要隐式转换.