重写引用的程序集的类

本文关键字:程序集 重写 引用 | 更新日期: 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 才能覆盖它们。