有没有类似于C#中显式接口实现的类似方法来实现类呢?
考虑以下情况:
公司X提供了一个包含如下类的库:
public class LibraryClass
{
public virtual void A() { }
public void DoWork()
{
// does something
}
}
Y公司在其产品中使用了这个库,并继承自LibraryClass
:
public class UserClass : LibraryClass
{
public virtual void B() { }
}
到目前为止,一切都运转良好。但某天X发布了一个新的库版本并向LibraryClass
添加了一个虚方法B()
:
public class LibraryClass
{
public virtual void A() { }
public virtual void B() { }
public void DoWork()
{
// does something
// now uses B with certain semantic assumptions
}
}
现在Y更新到了新的库版本。当使用对新版本的引用进行编译时,编译器会发出一个警告,指出隐藏了继承的方法,因此应该指定new关键字或覆盖该方法。由于现有的方法和新引入的方法之间存在语义差异,Y决定引入new关键字,因为任何现有的覆盖可能不会提供所期望的语义,这将导致代码出错。另一方面,Y想要使用库的一个新功能,这需要覆盖。现在这是不可能的:如果在的派生类中进行覆盖,由于new关键字,覆盖将引用;在本身中覆盖甚至是不允许的,因为它已经定义了具有该签名的公共方法。
如果在的派生类中有一种方式可以指定覆盖引用,那么这种情况就可以解决,但据我所知目前并不可行;或者如果中的可以被显式地覆盖,那么也可以解决这个问题。
public class UserClass : LibraryClass
{
...
// Override this method in order to change the behavior of LibraryClass.B()
public virtual void LibraryB() { }
private void override LibraryClass.B()
{
LibraryB();
}
...
}
除了重命名UserClass
中的原始B()
方法(如果它是由公司Z使用的库的一部分,则可能无法进行重命名),还有没有其他语言解决此问题的方法?如果没有,这是C#的限制还是CLR的限制?
对于这篇长文章表示抱歉,感谢您阅读到这里。
编辑:这不是CLR的限制。 C++ / CLI支持命名覆盖,可以解决此问题,因此您可以执行类似于virtual void LibraryB(void) = LibraryClass::B;
的操作。 C#设计团队可能只是忽略了这个问题。