覆盖泛型类型方法时的编译错误

Ada*_*one 5 .net c# generics inheritance

我在程序集A中公开以下类:

public abstract class ServiceDependencyHost
{
    protected virtual T ReferenceService<T>() where T : ServiceBase
    {
        // Virtual implementation here...
    }
}
Run Code Online (Sandbox Code Playgroud)

我在一个单独的程序集中公开了这个派生类(B):

public sealed class ProcessServiceOperation : ServiceDependencyHost
{
    public override T ReferenceService<T>()
    {
        // Override implementation here...

        return base.ReferenceService<T>();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用上面显示的代码,编译器在这一行上抱怨:

return base.ReferenceService<T>();
Run Code Online (Sandbox Code Playgroud)

类型'T'不能在泛型类型或方法A.ReferenceService()中用作类型参数'T'.没有从'T'到'System.ServiceProcess.ServiceBase'的装箱转换或类型参数转换.

当然,我尝试复制程序集B中的约束:

public override T ReferenceService<T>() where T : ServiceBase
Run Code Online (Sandbox Code Playgroud)

但编译器现在在上面的行上发出警告......

覆盖和显式接口实现方法的约束是从base方法继承的,因此不能直接指定它们.

这个答案表明我的解决方案应该有效.我想避免使用反射公开公开此方法.应该这么简单!

提前感谢任何能够发现我犯的错误的人.

小智 5

该错误消息似乎具有误导性。

请注意,您使用公共覆盖覆盖了受保护的虚拟方法。那是行不通的。也让覆盖受到保护,代码应该可以正常编译......

(我不确定看似错误的错误消息是否是一个小故障,或者编译器的这种特定行为背后是否有合理的解释。)


Dou*_*las 5

该问题并不完全是由于泛型引起的。问题的原因是基类方法是protected,而派生类方法是public

重写声明不能更改虚拟方法的可访问性。重写方法和虚拟方法必须具有相同的访问级别修饰符。

因此,编译器假定这两个方法是不同的,并且派生方法无法where T : ServiceBase从基方法继承通用约束。由于派生方法对 一无所知,因此当您尝试将其传递给基方法时,T它会抱怨T无法转换为。ServiceBase