【发布时间】:2019-05-22 17:06:35
【问题描述】:
如下代码所示,在两个不同的程序集中定义了两个接口IFoo:
/// assembly A
interface IFoo {
void DoSomething()
}
/// assembly B
interface IFoo {
void DoSomething()
void DoSomethingElse()
}
/// assembly C
class Bar : IFoo {
public virtual void DoSomething()
public virtual void DoSomethingElse()
}
假设程序集 A 和程序集 B 错误地具有相同的签名(程序集弱名称或强名称)。为 Bar 类生成的 MSIL 是否会因构建时使用的是程序集 A 还是程序集而有所不同?
换句话说,假设我们在运行时使用程序集 A 和 C 构建一个项目,在运行时将 A 替换为程序集 B 是否可以?否则我会得到诸如“IFoo.DoSomethingElse”之类的异常没有实现,因为在构建过程中DoSomethingElse被认为是一种新方法,而不是在接口中实现现有方法。
【问题讨论】:
-
AssemblyA.IFoo是与AssemblyB.IFoo不同的类型。它们具有相同的形状并不重要。如果你想动态构造一个对象,那么需要有一个类型,两个/所有目标类型共享(通过继承)。 -
您是否试图在不重新编译依赖程序以改变行为的情况下有意换出 DLL,您是否试图确保恶意用户在运行时不会更改 DLL,从而改变其行为?试图防止由于巧合的名称冲突或其他原因而意外改变行为?
-
@KennethK.as 我已经提到,这两个程序集具有相同的强名称。
-
@Servy,我正在尝试将 DLL 替换为“hacky”热修复程序。这是一个复杂的故事,但简而言之,我们的一个服务目前正在抛出异常,因为升级了依赖项(向其接口添加了一个方法),但由于某些原因,我们不能简单地在运行时升级依赖项,所以我是想知道我是否可以在编译时简单地“添加一个新方法”,并希望它会在运行时“实现”该接口。
-
C# v8 的默认接口方法特性就是为了解决这类问题。为时已晚,您必须编辑/重建该程序集。