继承和扩展方法

5

考虑下面这段简单的代码:

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方法?


3
使用扩展方法无法实现此目的。扩展方法在编译时解析,而您想要在运行时进行检查。 - xanatos
2
扩展方法不具有多态性。由于parameter是一个Base,即使传递的对象实际上是一个Derived,也会调用扩展Base的方法。您可以通过提供一个接受Derivedtest()重载来解决这个问题,但如果您有许多派生类,这种解决方案就不太可行了。 - Frédéric Hamidi
((Derived)parameter).Validate();,但你应该寻找另一种解决问题的方法。这会让维护变成噩梦。 - Brad Christie
@xanatos 好的,但即使是使用常规的静态方法,我也得到了相同的结果。看来我需要选择另一种方式去做。 - Somebody Please Help me
@BradChristie 很好的观点,这个噩梦正是我试图避免的事情之一。 - Somebody Please Help me
显示剩余2条评论
1个回答

3
您想要一个虚拟扩展方法,但是它不被支持。扩展方法只是静态方法调用的语法糖,在编译时绑定。您需要通过查看运行时类型来添加一些动态分派,以确定应该调用哪个扩展方法。
在您的情况下,为什么不将“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");
    }
}

鉴于问者首先使用了扩展方法,很有可能他们无法访问“基类”和“派生类”的实现。 - Frédéric Hamidi
@FrédéricHamidi 可能是可以的,但提供的代码并没有表明这一点。 - D Stanley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接