如何强制调用C#派生方法

Hen*_*gyi 7 c# inheritance class

我有一个由某个工具生成的类,因此我无法更改它.生成的类非常简单(没有接口,没有虚拟方法):

class GeneratedFoo
{
  public void Write(string p) { /* do something */ }
}
Run Code Online (Sandbox Code Playgroud)

在C#项目中,我们想提供一种方法,以便我们可以插入MyFoo的不同实现.所以我想让MyFoo从GeneratedFoo派生

class MyFoo : GeneratedFoo
{
  public new void Write(string p) { /* do different things */ }
}
Run Code Online (Sandbox Code Playgroud)

然后我有一个CreateFoo方法,它将返回GeneratedFoo或MyFoo类的实例.但是它总是调用GeneratedFoo中的方法.

GeneratedFoo foo = CreateFoo(); // if this returns MyFoo,
foo.Write("1"); // it stills calls GeneratedFoo.Write
Run Code Online (Sandbox Code Playgroud)

这是因为它不是虚方法而被删除.但我想知道是否有一种方法(可能是黑客)让它调用派生方法.

谢谢,
伊恩

Mar*_*uła 22

亚当给了你答案(正确的答案).现在是你要求的黑客的时间:)


class BaseFoo
{
    public void Write() { Console.WriteLine("Hello simple world"); }
}

class DerFoo : BaseFoo
{
    public void Write() { Console.WriteLine("Hello complicated world"); }
}

public static void Main()
{
    BaseFoo bs = new DerFoo();
    bs.Write();

    bs.GetType().GetMethod("Write").Invoke(bs, null);
}
Run Code Online (Sandbox Code Playgroud)

打印出来:

Hello simple world
Hello complicated world


Ada*_*son 6

没有能够使方法虚拟,没有.非虚方法在编译时静态链接,不能更改.


Tul*_*x86 6

编写一个安全播放到派生类型的扩展方法,然后根据引用调用该方法.

public static class Extensions
{
  public static void WriteFoo(this GeneratedFoo foo, string p)
  {
     MyFoo derived = foo as MyFoo;
     if (derived != null)
     {
        derived.Write(p);
     }
     else
     {
        foo.Write(p);
     }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后用它来调用它

GeneratedFoo unknownFoo;
unknownFoo.WriteFoo("win");
Run Code Online (Sandbox Code Playgroud)

注意:这是一个肮脏的黑客.一个更清晰的解决方案是问问自己为什么首先需要使用new修饰符.重载意义Write(p)会使代码混淆维护者.您可以轻松地声明它public void WriteToTarget()或更具体的东西,以避免混乱.