我在程序集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
但是编译器现在警告上面的那行...
覆盖和显式接口实现方法的约束是从base方法继承的,因此不能直接指定它们。
This answer表示我的解决方案应该有效。我想避免使用反射公开公开此方法。应该这么简单!
提前感谢任何能够发现我犯了什么错误的人。
答案 0 :(得分:4)
错误消息似乎具有误导性。
请注意,您使用公开覆盖覆盖了受保护的虚拟方法。那不行。使覆盖也受到保护,代码应该编译得很好......
(我不确定看似错误的错误消息是否是一个小问题,或者编译器的这种特殊行为背后是否有合理的解释。)
答案 1 :(得分:4)
问题并非严格归因于仿制药。问题的原因是基类方法是protected
,而派生类方法是public
。
覆盖声明无法更改虚拟方法的可访问性。覆盖方法和虚方法都必须具有相同的访问级别修饰符。
因此,编译器假定这两个方法是不同的,并且派生方法无法从基本方法继承where T : ServiceBase
泛型约束。由于派生方法对T
一无所知,因此当您尝试将T
传递给基本方法时,它会抱怨ServiceBase
无法转换为{{1}}。
答案 2 :(得分:1)
因为公共=&gt;保护。编译好
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>();
}
}