【问题标题】:Compilation error when overriding a generic type method覆盖泛型类型方法时出现编译错误
【发布时间】:2014-01-12 14:49:23
【问题描述】:

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

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

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

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

        return base.ReferenceService<T>();
    }
}

使用如上所示的代码,编译器在这一行报错:

return base.ReferenceService<T>();

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

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

public override T ReferenceService<T>() where T : ServiceBase

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

覆盖和显式接口实现方法的约束是从基方法继承的,所以不能直接指定。

This answer 表示我的解决方案应该有效。我想避免使用反射来公开这种方法。应该就是这么简单!

提前感谢任何能发现我所犯错误的人。

【问题讨论】:

    标签: c# .net generics inheritance


    【解决方案1】:

    严格来说,这个问题并不是由泛型引起的。问题的原因是基类方法是protected,而派生类方法是public

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

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

    【讨论】:

    • 在 elgonzo 的帖子下查看我的评论。谢谢,道格拉斯。我想知道为什么编译器让我误入歧途:-P
    • 啊,您对编译器为什么会发出错误消息的解释是有道理的。它归结为编译器进行健全性检查的顺序以及他首先失败的顺序......
    【解决方案2】:

    错误信息似乎具有误导性。

    请注意,您使用 public 覆盖覆盖了 protected 虚拟方法。那是行不通的。使覆盖也受到保护,代码应该编译得很好......

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

    【讨论】:

    • 啊哈!我知道我是个白痴,我只需要有人把我的脸指向水平。因此,如果我想公开它,我需要创建一个新的公共方法并调用 A.ReferenceService。谢谢,埃尔贡佐。
    • @AdamStone,鉴于道格拉斯提供了有关错误消息的解释,我认为应该标记他的答案而不是我的答案。 :)
    • @AdamStone:不! ;-)
    【解决方案3】:

    它是因为公共 => 受保护的。这编译得很好

    public abstract class ServiceDependencyHost
            {
                protected virtual T ReferenceService<T>() where T : new()
                {
                    return new T();
                }
            }
    
            public sealed class ProcessServiceOperation : ServiceDependencyHost
            {
                protected override T ReferenceService<T>()
                {
                    // Override implementation here...
    
                    return base.ReferenceService<T>();
                }
            }
    

    【讨论】:

    • 我讨厌解决方案与您认为的问题无关。这几乎总是会发生。因此,我讨厌问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    相关资源
    最近更新 更多