【问题标题】:Exact meaning of "new" on member declarations [duplicate]成员声明中“新”的确切含义[重复]
【发布时间】:2013-11-30 02:23:04
【问题描述】:

我见过这样声明的方法:

public void new SortItems()

这实际上是做什么的?我知道new 关键字是用来调用构造函数的,但我在方法定义上也看到过,比如上面的例子。

【问题讨论】:

    标签: c# .net oop inheritance member


    【解决方案1】:

    应该是这样的:

    public new void SortItems(){
      //...
    }
    

    这个new 关键字用于隐藏具有相同名称(用于属性、事件...)和相同签名(用于方法)的基本成员(方法、属性...),在这种情况下它是方法SortItems。它与 new 在创建新实例方面不同。无论是否使用new 来隐藏基类中的冲突 成员,要访问基类成员,您必须使用关键字base 在派生类中访问它。

    【讨论】:

      【解决方案2】:

      当使用这种方式时,它是一个修饰符。它用于隐藏继承的成员而不是覆盖它。如果基本方法是密封的,这很有用。下面是一个简单的示例来演示覆盖和隐藏继承成员之间的区别:

      public class Foo
      {
          public virtual void OverriddenMethod() { Console.WriteLine("foo"); }
          public void HiddenMethod() { Console.WriteLine("foo"); }
      }
      
      public class Bar : Foo
      {
          public override void OverriddenMethod() { Console.WriteLine("bar"); }
          public new void HiddenMethod() { Console.WriteLine("bar"); }
      }
      
      void Main()
      {
          Bar bar = new Bar();
          Foo foo = bar;
          bar.OverriddenMethod(); // "bar"
          bar.HiddenMethod();     // "bar"
          foo.OverriddenMethod(); // "bar"
          foo.HiddenMethod();     // "foo"
      }
      

      进一步阅读

      【讨论】:

      • 简短说明:new 修饰符对继承没有任何作用。在阴影的情况下,它只是抑制编译器警告。
      【解决方案3】:

      在方法签名中使用时,意味着定义它们的类的实现细节不同。这种方法的问题是它没有被多态地使用,所以:

      class Thing
      {
          void DoSomething()
          {
              Console.WriteLine("Thing");
          }
      }
      
      class Other : Thing
      {
          new void DoSomething()
          {
              Console.WriteLine("Other");
          }
      }
      
      var thing = new Thing();
      thing.DoSomething(); \\ prints Thing
      
      var other = new Other();
      other.DoSomething(); \\ prints Other
      
      ((Thing)other).DoSomething(); \\ prints Thing
      

      【讨论】:

      • 我想补充一点,应该避免这种情况。如果过度使用,可能会出现各种意外行为。
      【解决方案4】:

      它与覆盖相反。假设你有:

      public class A
      {
          public virtual void f() { Console.WriteLine( "A" ); }
      }
      public class B : A
      {
          public override void f() { Console.WriteLine( "B" ); }
      }
      
      public class C : A
      {
          public new void f() { Console.WriteLine( "C" ); }
      }
      

      然后在 main:

      A b = new B();
      A c = new C();
      
      b.f();
      c.f();
      (c as C).f();
      

      这将打印:

      B
      A
      C
      

      只有当类型为定义类时才会调用new方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-09
        • 1970-01-01
        • 2017-08-04
        相关资源
        最近更新 更多