Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#泛型扩展方法的专门化_C#_Generics_Extension Methods - Fatal编程技术网

C#泛型扩展方法的专门化

C#泛型扩展方法的专门化,c#,generics,extension-methods,C#,Generics,Extension Methods,我的MessageBus有以下扩展方法: public static class MessageBusMixins { public static IDisposable Subscribe<T>( this IObservable<T> observable, MessageBus bus) where T:class { ... } public static IDisposab

我的
MessageBus
有以下扩展方法:

public static class MessageBusMixins
{
    public static IDisposable Subscribe<T>(
        this IObservable<T> observable,
        MessageBus bus)
    where T:class
    {
        ...
    }

    public static IDisposable Subscribe<T>( 
        this IObservable<Maybe<T>> observable,
        MessageBus bus)
    {
        ...
    }
}

然后它工作并选择正确的方法。

好的,您可以通过指定类型参数来修复它:

source.Subscribe<string>(bus);
source.Subscribe(总线);
。。。因为现在只有第二种方法适用

否则,编译器可能会调用以下任何一种:

source.Subscribe<string>(bus);
source.Subscribe<Maybe<string>>(bus);
source.Subscribe(总线);
来源:订阅(公交车);
如果您认为第一个比第二个更具体,那么您必须在C#规范中找到这样的规则:)这不是一个不合理的期望,但我不认为常规的“更具体”转换适用于类型参数以及常规参数

例如,在C#4规范的第7.5.3.2节(“更好的功能成员”)中,有一条关于:

  • 否则,如果MP具有比MQ更具体的参数类型,则MP优于MQ。[…关于更少/更具体的许多细节…]
。。。但是关于类型参数没有类似的观点。(关于普通参数的第二部分讨论类型参数,但这在参数类型本身内部。)


另一种选择是简单地给方法起不同的名字。他们的行为有细微的不同吗?如果是这样的话,为什么不通过命名让这一点变得非常明显呢?你真的不希望有人仅仅因为对调用的重载感到惊讶而得到错误的行为。

你可以让它按预期工作:
publicstaticidisposable-Subscribe(这个IObservable-observable,MessageBus-bus)其中T:Maybe
@2kay通用约束不是候选解析过程的一部分,因此这不起作用。我已经用直接调用扩展方法更新了这个问题,它会给出不同的结果。为什么扩展方法不能专门化,而直接调用却不能。这是否符合您对标准的理解。在这种情况下,我将使用直接调用,因为它对我来说是编译时安全的。
source.Subscribe<string>(bus);
source.Subscribe<string>(bus);
source.Subscribe<Maybe<string>>(bus);