假设我们在 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";
此代码在针对新接口定义运行时会失败,并出现如下异常:
System.MissingMethodException:找不到方法:'Void MyNamespace.IBase.set_Prop2(System.String)'。
注意对 的引用IBase
。我认为这是因为看似对的调用ISub1.set_Prop2
已编译为与Prop2
实际引入的位置紧密绑定,在IBase
.
谁能帮我解决这个难题?即有没有办法重构接口,使 ISub2 的定义是“干净的”(不包括无关的 Prop2)?要求所有现有的应用程序重新编译是不可能的。