繁体   English   中英

如何克服C#对泛型约束进行重载的限制?

[英]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; }
}

使用此代码,我试图允许调用:

  1. IjQueryPromiseIjQueryPromise<TResult>上具有不IjQueryPromise IjQueryPromise<TResult>回调的Done()
  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM