[英]How to overcome the C# limitation to overload on generic constraint?
让我们有以下代码(jQuery的类型安全存根):
public interface IjQueryPromise { }
public interface IjQueryPromise<TResult> : IjQueryPromise { }
public static class jQueryPromiseEx
{
public static T Done<T>(this T t, params Action[] doneCallbacks)
where T : IjQueryPromise { return t; }
public static T Done<T, TResult>(this T t, params Action<TResult>[] doneCallbacks)
where T : IjQueryPromise<TResult> { return t; }
}
使用此代码,我试图允许调用:
IjQueryPromise
或IjQueryPromise<TResult>
上具有不IjQueryPromise
IjQueryPromise<TResult>
回调的Done()
IjQueryPromise<TResult>
上使用带一个参数TResult
类型的回调的Done()
。 但是由于C#(v5.0)无法在通用约束上重载,因此像下面那样传递lambda:
(r) => DoSomething(r)
会产生编译错误:
委托“ System.Action”不带1个参数。
我将这些方法实现为扩展方法,以返回调用该函数的对象的类型。
我唯一的想法就是自动内联接口及其所有实现中的代码。
是否可以用C#更好的方式解决此问题?
还是已经存在进行内联的工具?
编辑 :我正在为开发人员设计API。 我知道我可以强制委托,但是我不希望开发人员(API的用户)每次都被强制强制强制委托。
这不是过载解析的问题。
它与另一个重载冲突无关。
这是类型推断的问题。 如果您没有指定lambda的参数类型或整个委托的类型,则第二个重载将无法推断TResult
的类型。
只需从应用程序中完全消除第一个重载就可以很容易地看到这一点。 所有要做的就是将错误消息从您得到的内容更改为一种说法,即类型推断失败。
既可以允许类型推断又实际上不提供其他类型信息(即为lambda参数键入类型)的一种方法是将其简化为一个通用参数:
public static IjQueryPromise<T> Done<T>(this IjQueryPromise<T> t,
params Action<T>[] doneCallbacks)
{ return t; }
问题是c#无法推断匿名方法中参数的类型。
如果您以这种方式声明参数类型,它将起作用;
IjQueryPromise<int> promise;
promise.Done( (int r) => DoSomething(r) ); // This should work as expected
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.