Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这个“问题”有什么影响;新";在C#中有关键字,为什么不使用时只是一个警告?_C#_New Operator_Warnings_Keyword - Fatal编程技术网

这个“问题”有什么影响;新";在C#中有关键字,为什么不使用时只是一个警告?

这个“问题”有什么影响;新";在C#中有关键字,为什么不使用时只是一个警告?,c#,new-operator,warnings,keyword,C#,New Operator,Warnings,Keyword,考虑以下代码: public abstract class Test1 { public object Data { get; set; } } public abstract class Test2<T> : Test1 { public T Data { get; set; } } 公共抽象类Test1 { 公共对象数据{get;set;} } 公共抽象类Test2:Test1 { 公共T数据{get;set;} } 这将生成以下警告: “Test2.Dat

考虑以下代码:

public abstract class Test1
{
    public object Data { get; set; }
}

public abstract class Test2<T> : Test1
{
    public T Data { get; set; }
}
公共抽象类Test1
{
公共对象数据{get;set;}
}
公共抽象类Test2:Test1
{
公共T数据{get;set;}
}
这将生成以下警告:

“Test2.Data”隐藏继承的成员“Test1.Data”。如果要隐藏,请使用新关键字

为什么这只是一个警告?添加“new”关键字会有什么影响

根据我的测试,一旦添加了“new”关键字,我就找不到任何区别

别误会,我完全赞成直截了当,但我很好奇添加“new”的好处

我对它可能是什么的唯一想法是:

  • 提高人类可读性
  • 在运行时,如果编译器没有在很长一段时间内找出不可避免的问题,那么可以节省一些时间

    • 关键字的唯一作用是删除警告。在不使用
      new
      关键字时获取警告的目的是防止您在真正打算覆盖该方法时意外隐藏该方法。

      将报告警告作为错误启用。这将迫使您更明确地使用new和override。

      new
      用于隐藏基类的方法或属性。这与重写它不同:成员不需要与隐藏的基类成员具有相同的签名,并且不涉及多态性

      例如:

      class A
      {
          public virtual void Test()
          {
              Console.WriteLine("A.Test");
          }
      }
      
      class B : A
      {
          public new void Test()
          {
              Console.WriteLine("B.Test");
          }
      }
      
      class B : A
      {
          public override void Test()
          {
              Console.WriteLine("C.Test");
          }
      }
      
      public static void Main(string[] args)
      {
          A aa = new A();
          aa.Test(); // Prints "A.Test"
      
          A ab = new B();
          ab.Test(); // Prints "A.Test" because B.Test doesn't overrides A.Test, it hides it
      
          A ac = new C();
          ac.Test(); // Prints "C.Test" because C.Test overrides A.Test
      
          B b = new B();
          b.Test(); // Prints "B.Test", because the actual type of b is known at compile to be B
      }
      

      派生类方法是否应被视为同名基类方法的重写通常取决于派生类方法的作者是否知道基类方法及其关联的约定,并编写派生类方法以实现该约定。在大多数情况下,如果派生类方法与基类方法具有相同的名称和签名,则派生类方法将用于履行基类约定,但如果部署基类的作者添加了一个名称,而没有意识到该名称在派生类中用于其他目的,不能假定派生类方法作者编写的方法符合当时不存在的基类方法的约定

      C#无法判断何时向类中添加了不同的方法,因此,编译器无法知道派生类方法的作者是否知道类似命名基类方法的存在,除非派生类方法的作者通过使用
      new
      覆盖
      修改器

      我建议将修饰语(或缺少修饰语)解释为:

      • 无——作者不知道基类方法的存在,因此不能期望实现其契约

      • new
        ——作者知道基类方法,并且出于任何原因编写了此方法以避免实现它

      • override
        ——作者了解基类方法及其契约,并编写此方法来实现它


      编译器默认为假定
      new
      ,但带有警告的原因是,如果在基类方法存在之前将该方法添加到派生类中,作者不可能知道基类约定,也不可能有理由打算履行一个还不存在的约定,但是如果派生类方法是在基类方法之后编写的,作者通常应该选择另一个名称,除非作者打算履行基类契约,或者有特定的理由在不履行契约的情况下使用相同的名称。编译器无法分辨哪个方法是先编写的,因此无法知道哪个行为是合适的。

      new不做任何事情(除了抑制警告)。隐藏是通过省略覆盖来实现的。是的,但是通过指定
      new
      关键字,可以显式隐藏成员。虽然它最终没有改变任何事情,但它证明了你知道自己在做什么,并且没有意外地忘记了
      覆盖
      关键字不,隐藏也会发生w/o new我从来没有说过它没有。。。我只是说,通过使用
      new
      关键字,您可以显式地隐藏成员,因此您的意图不会模棱两可