【问题标题】:Inheritance and extension method继承和扩展方法
【发布时间】:2015-06-26 15:08:00
【问题描述】:

考虑这个简单的代码:

public void Main()
{
    var d = new Derived();

    test(d);
}

public void test(Base parameter)
{
    parameter.Validate();
}

public class Base
{
}
public class Derived : Base
{
}

public static class Validation
{
    public static void Validate(this Base b)
    {
        Console.WriteLine("Validation for base");
    }
    public static void Validate(this Derived d)
    {
        Console.WriteLine("Validation for Derived");
    }
}

当调用测试方法时,它将执行接受基本参数的 Validate 方法,而不是像我调用了 d.Validate() 一样。

如何强制测试方法调用正确的 Validate 方法,而不在其中进行类型测试?

【问题讨论】:

  • 你不能通过使用扩展方法。扩展方法在编译时解析,而您希望在运行时进行检查。
  • 扩展方法不是多态的。由于parameterBase,因此即使传递的对象实际上是Derived,也会调用扩展Base 的方法。您可以通过提供采用Derivedtest() 重载来解决此问题,但如果您有许多派生类,此解决方案无法很好地扩展。
  • ((Derived)parameter).Validate();,但您应该寻找另一种剥猫皮的方法。这使得维护成为一场噩梦。
  • @xanatos 好的,但即使使用常规的静态方法,我也会得到相同的结果。看来我得另选路了
  • @BradChristie 好点,这场噩梦正是我想要避免的事情之一。

标签: c# inheritance extension-methods


【解决方案1】:

您想要一个不受支持的 virtual 扩展方法。扩展方法只是在编译时绑定的静态方法调用的语法糖。您必须通过查看运行时类型来添加一些动态调度,以查看应该调用哪个扩展方法。

在您的情况下,为什么不将Validate 设为基类的虚拟方法?

public class Base
{
    public virtual void Validate()
    {
        Console.WriteLine("Validation for base");
    }
}
public class Derived : Base
{
    public override void Validate()
    {
        base.Validate();  // optional
        Console.WriteLine("Validation for Derived");
    }
}

【讨论】:

  • 由于提问者首先使用了扩展方法,因此他们可能无法访问BaseDerived 的实现。
  • @FrédéricHamidi 这是可能的,但提供的代码并未表明这一点。
猜你喜欢
  • 2017-03-16
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多