假设我们在C#中定义了一个基本接口:
interface IBase
{
int Prop1 { get; set }
string Prop2 { get; set }
}
然后我们有以下派生接口:
interface ISub1: IBase
{
int Prop3 { get; set }
}
这些接口在API程序集中定义,定制应用程序编译和运行时使用该程序集。(该程序集还包括未公开的类来实现这些接口和用于获取实例的公共工厂方法)。所有现有代码都使用ISub1,没有直接引用IBase的现有代码。这样做是为了预计我们可能最终想引入第二个派生接口ISub2,作为ISub1的同级接口,并且现在已经实现。不幸的是,我们发现ISub2不应该包含Prop2(只包含Prop1和一些其他独特的属性),因此我们希望将该属性“降级”到ISub1中,从而得到以下修订后的接口:
interface IBase
{
int Prop1 { get; set }
}
interface ISub1: IBase
{
string Prop2 { get; set }
int Prop3 { get; set }
}
interface ISub2: IBase
{
string Prop4 { get; set }
}
考虑到IBase
没有消费者,我们应该可以毫无顾虑地这样做(我相信在Java中我们可以这样做),但是当我们试图这样做时,我们遇到了与旧接口定义编译的代码的二进制兼容性问题。具体来说:
ISub1 s1 = ... // get an instance
s1.Prop2 = "help";
当针对新接口定义运行此代码时,会出现以下异常:
请注意引用了`IBase`。我认为这是因为似乎对`ISub1.set_Prop2`的调用已经编译成与实际引入`Prop2`的地方即`IBase`进行了紧密绑定导致的。System.MissingMethodException:找不到方法:'Void MyNamespace.IBase.set_Prop2(System.String)'。
有人能帮我摆脱这个困境吗?也就是说,是否有一种重新设计接口的方式,使得`ISub2`的定义“干净”(不包括多余的`Prop2`)?要求所有现有应用程序重新编译是不可能的。