3

我在定义以下接口的应用程序中有一个程序集:

public void Method1()

然后我有一个实现这个接口的程序集插件。它是在运行时发现和加载的。

后来我修改了接口以包含一个新方法:

public void Method1()
public void Method2()

我创建了一个新的程序集插件来实现新版本的接口。

有没有办法只在应用程序上部署新界面和新插件?目前,客户端永远不会在第一个插件上调用 Method2(),所以它不应该是一个问题(如果在任何时候 Method2 在第一个插件上被调用,我可以抛出异常)。

我以为我可以做到,但我得到一个TypeLoadException说法:

来自程序集 'Provider2,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null' 的类型 'Provider2.Class2' 中的方法 'Method2' 没有实现。

(这是真的,但由于没有调用 Method2 应该不是问题)

4

2 回答 2

8

您不应该修改该接口。

接口通常以两种主要方式之一使用:

  1. 它们完全在应用程序内部使用
  2. 它们是公开的,因为其他人可以创建诸如插件之类的东西来实现或使用接口

在第一个选项中,您当然可以自由地对它做任何您想做的事情,比如向它添加新方法。如果这会产生很多编译器错误,那是您自己的问题,您也可以“轻松”修复这些错误。

在第二个选项中,您永远不应该修改该接口。相反,您应该使用新方法创建一个新接口,然后编写代码以使其同时支持旧接口和新接口。

当然,除非您想完全禁止旧类工作,否则您将重新开始做任何您想做的事情。

所以这里的答案是你不应该修改那个接口。而是使用新方法创建一个新接口,并同时支持旧版本和新版本。

每次更改接口时都应该努力使用这种方法,这包括更多类型的更改,而不仅仅是添加方法。

如果你改变了接口的含义,或者修复了重大的非灾难性的 bug,你可能想要引入一个新的接口,让旧的接口有旧的 bug。有人可能编写了依赖于旧行为的代码,无论好坏,你“修复”它可能会破坏过去工作的东西,即使编译器没有抱怨。

例如,假设您将比较结果传递给一个方法。您的文档指出,如果比较结果为<正,a 为正,a 为>0 ,则值将为负==

然后你突然发现你没有返回 -1、0 或 +1,而是返回 -N、0 和 +N,其中 N 是比较的副产品,例如 的结果A-B,所以在下一个版本中,您将其更改为 -1、0 和 +1。

某些代码可能依赖于这样一个事实,即这些值不仅代表比较的结果,而且确实是-N,因此您修复此问题会破坏该代码。

当然,依赖未记录的行为总是不好的,但同样,您的客户很可能会因为代码曾经可以工作而您的更新破坏了它这一事实而挂断电话。

于 2013-09-09T07:05:06.107 回答
2

因为没有调用 Method2 应该不是问题

.Net 中的类型不是这样工作的。如果你的类声称它实现了一个接口,那么它只需要实现那个接口。

您描述的内容类似于鸭子打字,而.Net 不使用它。

于 2013-09-09T10:44:28.260 回答