【问题标题】:What is the point of "static new" modifier for a function?函数的“静态新”修饰符有什么意义?
【发布时间】:2023-03-31 15:04:01
【问题描述】:

今天,我在遗留代码中发现了一些东西。它具有一项功能的“静态新”。看起来像这样。

class Foo
{
    public static void Do()
    {
        Console.WriteLine("Foo.Do");
    }
}

class Bar: Foo
{
    public static new void Do()
    {
        Console.WriteLine("Bar.Do");
    }
}

我不理解 Bar 类中 Do 方法的 static new 修饰符。在 C# 中,静态方法只能使用类名而不是对象名来调用。所以,我认为拥有“新”和没有“新”之间没有任何区别。

通常,如果某些语法是不必要的,C# 只是将其视为错误。 有人知道为什么 C# 允许这样的语法吗?

【问题讨论】:

    标签: c# static new-operator modifier


    【解决方案1】:

    如果您从代码中删除 new,您会得到:

    警告 CS0108:“Bar.Do()”隐藏了继承的成员“Foo.Do()”。如果要隐藏,请使用 new 关键字。

    C# 编译器只是警告您您可能正在做一些您不打算做的事情,并要求您插入 new 关键字以确认您知道自己在做什么。除了抑制警告,它没有其他作用。

    【讨论】:

    • 虽然它只抑制警告,但它使意图明确(以避免任何混淆),检查我的答案
    • 还要检查new modifier的文档。
    【解决方案2】:

    这仅适用于外部调用者。请记住,您可以调用基类的静态方法,所以这样的事情是有效的:

    class Foo
    {
        public static void Do() { Console.WriteLine("Foo.Do"); }
    }
    class Bar : Foo // :Foo added
    {
        public static void Something()
        {
            Do();
        }
    }
    

    这就是警告告诉你放新的原因,你想在这样做时避免任何混淆:

    class Foo
    {
        public static void Do() { Console.WriteLine("Foo.Do"); }
    }
    class Bar : Foo // :Foo added
    {
        public static void Something()
        {
            Do();
        }
        public static new void Do() { Console.WriteLine("Bar.Do"); }
    }
    

    【讨论】:

      【解决方案3】:

      看看this

      public class BaseC
      {
          public static int x = 55;
          public static int y = 22;
      }
      
      public class DerivedC : BaseC
      {
          // Hide field 'x'.
          new public static int x = 100;
      
          static void Main()
          {
              // Display the new value of x:
              Console.WriteLine(x);
      
              // Display the hidden value of x:
              Console.WriteLine(BaseC.x);
      
              // Display the unhidden member y:
              Console.WriteLine(y);
          }
      }
      /*
      Output:
      100
      55
      22
      */
      

      为了清楚起见,你的例子应该是

      public class Foo
      {
          public static void Do() {}
      }
      public class Bar :Foo
      {
          public new static void Do() {}
      }
      

      【讨论】:

        【解决方案4】:

        在您的示例中,第二个类 Bar 似乎没有从 Foo 继承。这似乎是一个错字,因为否则没有意义。

        假设它是一个错字,“new”修饰符显式隐藏了函数Do() 的基类版本。这意味着Do() 方法的派生版本有效地替换了基类版本。

        在此处使用“new”记录了继承方法旨在替代Do() 的基类版本这一事实。

        欲了解更多信息,请参阅new Modifier (C#)

        【讨论】:

        猜你喜欢
        • 2011-03-01
        • 1970-01-01
        • 2018-08-15
        • 2018-04-24
        • 1970-01-01
        • 2011-10-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多