重写引用的程序集的类
本文关键字:程序集 重写 引用 | 更新日期: 2023-09-27 17:57:10
我有程序集A,A有两个类a和b。
A.a在某些方法中使用A.b。
在我的集会中,B,我有两个B.a和B.b类。
B.a 继承自 A.a,B.b 继承自 A.b。
如何在没有源代码的情况下让 B.a 在使用 A.b 的方法中使用 B.b 而不是 A.b?
如果没有 A
的源代码,并且 A 不会做任何花哨的事情,比如使用 IoC 解析 A.b,你就不能。 A.a 和 A.b 之间的依赖关系是在编译时设置的,可能没有简单的方法来拦截它。
如果 A.a 中使用 A.b 的方法是虚拟的,则可以覆盖它们,并改用 B.b 重现它们的功能。
没有无名会的支持?除了黑客反编译到 IL(ildasm)、更改然后重新编译 (ilasm) 之外,什么都没有。如果程序集 A 具有强名称(已签名),则不起作用
嗯,这里有两个问题。
首先,你应该使你打算从A.b中使用的A.a方法(从而在B.b中"替换")虚拟。这可确保您可以在 B.b 中覆盖它们。
但是,A.a 通过静态方法(无法重写)或通过 A.b 实例(您无法轻松替换)访问 A.b。
如上所述,除了使方法虚拟之外,您还需要做的是在 A.a 中提供一个工厂方法,用于创建 A.b 的实例,然后使用该结果,然后在 B.a 中重写此方法。
让我用这个 LINQPad 程序演示一下:
void Main()
{
Ba instance = new Ba();
instance.UseB();
}
public class Aa
{
public void UseB()
{
Ab instance = CreateB(); // <-- call factory method instead of new
instance.Test();
}
public virtual Ab CreateB()
{
return new Ab();
}
}
public class Ab
{
public virtual void Test()
{
Debug.WriteLine("A.b.Test");
}
}
public class Ba : Aa
{
public override Ab CreateB() // <-- it still returns type "Ab"
{
return new Bb(); // <-- just create an instance of Bb instead
}
}
public class Bb : Ab
{
public override void Test()
{
Debug.WriteLine("B.b.Test");
}
}
A
中的方法需要标记为 virtual
才能覆盖它们。