【问题标题】:C# Override static methodsC# 重写静态方法
【发布时间】:2019-03-21 18:42:59
【问题描述】:

我有以下类和方法

public class X
{
    public static void M1(...)
    {
        ...
        var isSomething = M2(...);
        ...
    }

    public static bool M2(...) { ... }
}

我需要实现一个新的具有相同签名的 M2 方法,以便在某些情况下调用。 为此,我想实现一个扩展 X 的新类 Y 并覆盖 M2 方法,所以当我调用 Y.M1() 时,我想使用 y.M2()。

public class Y : X
{
    public static [override] bool M2(...) { ... }
}

但是静态方法不能被覆盖。 任何人都可以建议我如何做到这一点?

【问题讨论】:

  • 您选择XY 作为示例类名有点有趣,因为这可能是XY problem。您能否为我们提供更多有关您正在尝试做的事情以及为什么要这样做的背景信息?
  • 这听起来确实像你实际上需要一些完全不同的东西,但只是假设覆盖一个静态方法将是解决方案。但是如果没有任何关于为什么需要这个的进一步信息,很难猜测。为什么不直接设置一些条件并调用一种方法或另一种方法?
  • @cesarfaria M2() 真的需要是静态的吗?如果没有,只需删除 static 修饰符。只要此方法不需要在不引用class X 实例的情况下从其他类调用,这始终是可能的。否则,为M2() 创建一个virtual 包装器并从M1() 调用它。然后用调用另一个M2()的方法覆盖这个。

标签: c# methods overriding


【解决方案1】:

静态方法不能被覆盖。 Dynamic binding 仅适用于对象实例。

您可以使用new 关键字从基类中“隐藏”静态方法,如here 所述。在您的情况下,您可以使用以下样式编写您的 Y.M2()

public class Y : X
{
    public static new bool M2(...) { ... }
}

请记住,这种样式与 normal 虚拟非静态方法覆盖不同。使用非静态方法覆盖,方法绑定根据实际对象类型在运行时完成。静态方法绑定在编译时完成。

【讨论】:

  • new 关键字只是消除了可能不希望隐藏继承成员的警告。但是,它并不能解决问题中所述的问题——也就是说,调用Y.M1() 仍将调用X.M2(),而不是Y.M2(),因为隐藏与覆盖不同。
【解决方案2】:

尚不完全清楚您要做什么,但据我了解您的问题,您想通过不同的静态方法 @987654323 更改由类 Y 继承的 M1() 的行为@。如果涉及的所有方法都是静态的,这是不可能的,但是如果您将 M1() 声明为非静态,则可以产生所需的效果。这可以通过这种方式完成:

public class X
    {
    public Boolean M1 (Int32 x1)
        {
        return M2 (x1);
        }
    public virtual Boolean M2 (Int32 x2)
        {
        return M3 (x2);
        }
    public static Boolean M3 (Int32 x2)
        {
        return x2 >= 0;
        }
    }

public class Y : X
    {
    public override Boolean M2 (Int32 x2)
        {
        return M3 (x2);
        }
    public static new Boolean M3 (Int32 x2)
        {
        return x2 < 0;
        }
    }

这是一个测试用例:

Boolean fTest1 = new X ().M1 (1);
Boolean fTest2 = new Y ().M1 (1);

Console.Write ("{0} {1}", fTest1, fTest2);

这将输出:

True False

所以包装器方法M2(),调用X中的静态方法M3()virtual,可以在Y中被覆盖,调用不同的静态方法M3()。因此,如果您使用派生类Y 的实例,则在继承方法M1() 内对M2() 的调用将被定向到M2()Y 内被覆盖的方法,该方法又调用另一个M3(),具有所需的行为变化 - 在此示例中,结果是反布尔值。

【讨论】:

  • 谢谢,我在想我只能使用静态方法来做到这一点,就像 Risto M 在之前的答案中建议的那样,但不起作用。
  • @cesarfaria 是的,这里的问题是静态方法可以被隐藏,但不能被覆盖。那是两种不同的东西。您需要重写以将调用定向到继承的类,因此必须在某处涉及虚拟方法。坦白说,不久前我自己也遇到过类似的问题,希望我可以重写一个静态方法。
猜你喜欢
  • 2013-01-27
  • 1970-01-01
  • 2011-05-10
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-12-27
  • 2011-05-17
  • 1970-01-01
相关资源
最近更新 更多