繁体   English   中英

具有泛型参数约束的子类中的新虚拟方法

[英]new virtual method in subclass with generics parameters constraints

我试图理解一段已简化为以下代码段的代码:

abstract class A_base {}
abstract class A_derived : A_base {}

abstract class B_base {
    protected virtual T Foo<T>() where T : A_base, new() {
        return new T();
    }
}

abstract class B_derived : B_base {
    protected new virtual T Foo<T>() where T : A_derived, new() {
        return base.Foo<T>();
    }
}

具体来说,我试图了解B_derived类的Foo方法中new virtual方法背后的B_derived 据我了解,作者希望收紧Foo方法的泛型参数(从A_baseA_derived ),同时还要让从B_derived派生的类重写Foo方法。

当前在从B_baseB_derived派生的任何类中都没有重写的Foo实现。

还有其他原因吗? 这样做有什么陷阱吗? 这是在重写方法中限制类型参数的常用方法吗? 还是做事复杂,有更好的办法?

原因如下:

  1. [回答使用New]请注意,Foo没有被覆盖。 由于覆盖需要相同的方法签名(包括约束)。 在这种情况下,约束条件正在改变,从而有效地改变了整个签名。 因此,采用了新的虚拟关键字。

  2. [答案的使用]现在作者希望将B_base.Foo()和B_derived.Foo视为第1点中所述的不同方法,并且他还希望用户应该能够覆盖这些不同的方法,因此需要使用虚拟关键字。

这是处理可能需要解决的方法问题的一种常见方式,当一个人需要更改方法的签名并且还希望具有覆盖每个单独方法的能力时。

通过说new virtual您可以创建一个新方法来遮盖原始方法(不会覆盖基类版本)。 这意味着,被称为从派生的类的任何方法B_derived其由类型的变量称为B_derived将使用新的方法签名(和功能)。 这也意味着无法覆盖原件,因为原件已被有效地从方法列表中删除。

为了有一个更具体的例子,我添加了一些类和一些日志记录。

abstract class A_base {}
abstract class A_derived : A_base {}

abstract class B_base {
   public virtual T Foo<T>() where T : A_base, new() {
      Console.Write("1");
      return new T();
   }
}

abstract class B_derived : B_base {
   public new virtual T Foo<T>() where T : A_derived, new() {
      Console.Write("2");
      return base.Foo<T>();
   }
}

class C1 : A_base {}
class C2 : A_derived {}

class D1 : B_base {
   public override T Foo<T>() {
      Console.Write("3");
      return base.Foo<T>();
   }

   //override T Foo<T>() where T : A_derived, new() {
   //    //Error constraint mismatch
   //}
}

class D2 : B_derived {
   public override T Foo<T>()  {
      Console.Write("4");
      return base.Foo<T>();
   }

   //override T Foo<T>() where T : A_base, new() {
   //    //Error constraint mismatch
   //}
}




public class Program
{
   public static int Main(string[] args) {
      //Comments are what is printed out.
      var d1 = new D1();
      var d2 = new D2();
      d1.Foo<C1>(); //31
      Console.WriteLine ();
      d1.Foo<C2>(); //31
      Console.WriteLine ();
      //d2.Foo<C1>(); //Error constraint mismatch
      d2.Foo<C2>(); //421
      Console.WriteLine ();
      B_base b_d2 = d2;
      b_d2.Foo<C1>(); //1
      Console.WriteLine();
      b_d2.Foo<C2>(); //1
      Console.WriteLine ();
      return 0;
   }
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM