我是一名程序员,我很懒惰。目前我正在使用 C# 中的一些 OpenAL 包装器。每次调用 OpenAL 方法时,我都必须使用 GetError
从 OpenAL 请求错误,如果有错误,我将抛出异常。没过多久,我添加了一个包含以下函数的静态帮助器类:
public static void Check()
{
ALError error;
if ((error = AL.GetError()) != ALError.NoError)
throw new InvalidOperationException(AL.GetErrorString(error));
}
这工作了一段时间,但我想要更多。所以,经过一段时间,我想出了以下方法:
public static void Call(Action function)
{
function();
ALHelper.Check();
}
public static void Call<TParameter>(Action<TParameter> function, TParameter parameter)
{
function(parameter);
ALHelper.Check();
}
public static TReturn Eval<TReturn>(Func<TReturn> function)
{
var val = function();
ALHelper.Check();
return val;
}
public static TReturn Eval<TParameter, TReturn>(Func<TParameter, TReturn> function, TParameter parameter)
{
var val = function(parameter);
ALHelper.Check();
return val;
}
效果很好,但我仍然对代码在使用时的外观不满意,所以我决定更进一步:我将上述方法转换为扩展方法。据我所知,我可以将方法作为 Action
和 Func
参数传递,我认为它也适用于扩展方法,将丑陋的 handles = ALHelper.Eval (AL.GenBuffers, amount)
变成更优雅的 handles = AL.GenBuffers.Eval(amount)
。
可悲的是,一旦我开始使用它,我就受到了欢迎:表达式表示一个方法组',其中需要一个
变量'、值'或
类型' .
有点难过这行不通,实际上我很好奇为什么这行不通。您可以将方法作为 Action
或 Func
传递,但使用扩展方法却不起作用的确切原因是什么?这是我正在使用的 Mono 编译器 (.NET 4.0) 的限制,还是内部有其他问题?
最佳答案
我认为您误解了扩展方法的概念。它们用于扩展类型。在这种情况下,AL.GenBuffers
是一种方法,它不是 Func
或 Action。
它的签名可能与它们兼容,但它不兼容'意味着它是一个函数或 Action 或任何其他类型的委托(delegate)类型。在您的示例中,由于 method group conversions,您可以像 AL.GenBuffers
一样传递它.当编译器发现方法签名兼容时,它会将其转换为 delegate
类型。
关于c# - 常规方法的 Action/Func 扩展方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26439683/