泛型类型约束似乎没有约束任何东西

本文关键字:约束 任何东 泛型类型 | 更新日期: 2023-09-27 18:00:47

我在调用泛型方法方面遇到了一些问题。 在下面的示例中,当我从基类调用ServiceCar时,当该方法在 Dealer 中定义为时,我会收到错误:

定义 1:ServiceCar<C>(C carToService) where C : Car<C> .

但是当该方法在 Dealer 中定义为时,我在基类中没有收到错误:

定义2:ServiceCar<C>(Car<C> carToService) where C : Car<C>

public abstract class Car<T> where T: Car<T>
{
     public bool isServiced;
     public string serviceMessage;
     public virtual void SendToService()
     {
          Dealer.ServiceCar<T>(this);       // error here when Definition 1 used
          serviceMessage = "Your car is clean.";
     }
 }
 public class Ford: Car<Ford>
 {
      public override void SendToService()
      {
           Dealer.ServiceCar<Ford>(this);
           serviceMessage = "Your Ford is clean.";
      }
 }
 public class Dealer
 {
      // When the parameter is defined as C (as commented below) an error occurs
      // When the parameter is defined as Car<C> there are no errors
      // public static void ServiceCar<C>(C carToService) where C : Car<C>
      public static void ServiceCar<C>(Car<C> carToService) where C : Car<C>
      {
           carToService.isServiced = true;
      }
 }

我的困惑是Microsoft说"其中 T: 表示类型参数必须是或派生自指定的基类"好吧,在定义 1(不编译(的情况下,C 是Car<C> . 那么为什么类型约束参数对我没有帮助。 我收到的错误是"...无法从 Car<T> 转换为 T"我错过了什么?

泛型类型约束似乎没有约束任何东西

尝试调用时

public static void ServiceCar<C>(C carToService) where C : Car<C> 

有了这个

Dealer.ServiceCar<T>(this);

您正在将类型 Car<T> 的表达式传递给需要类型 T 表达式的方法。它想要一个 T 类型的表达式的原因是Dealer.ServiceCar<T>显式地将C定义为 T ,所以 carToService 参数必须是T

但是,Car<T>不能转换为T。为什么会这样?它不继承自T .它唯一继承的是 object .因此,编译器无法将 Car<T> 类型的表达式转换为 T 类型的表达式,正如所示。

需要明确的是,您站点的文档和类定义指出T必须从Car<T>继承,但它没有说相反,Car<T>必须从T继承。

我认为您混淆了不同类型的参数。类 Car<T> 具有参数 T 和方法 ServiceCar<C> 具有另一个类型参数C。因此,您需要在方法和类声明中同时指定类型参数:

ServiceCar<C, T>(C carToService) where C : Car<T>

随手看起来就像你令人困惑的泛型和继承。请记住,其他开发人员在继承您的代码时可能需要执行的操作。如果可能的话,我总是选择简单。

public abstract class Car
{
     public bool isServiced;
     public string serviceMessage;
     public abstract string TypeName { get; }
     public virtual void SendToService()
     {
          Dealer.ServiceCar(this);       // error here when Definition 1 used
          servicesMessage = string.Format("Your {0} is clean.", Car.TypeName);
     }
 }
 public class Ford: Car
 {
      public override string TypeName { get { return "Ford"; } }
      //No need to override this because Ford inherits from Car
      //public override void SendToService()
      //{
      //     Dealer.ServiceCar<Ford>(this);
      //     serviceMessage = "Your Ford is clean.";
      //}
 }
 public class Dealer
 {
      public static void ServiceCar(Car carToService)
      {
           carToService.isServiced = true;
      }
 }

在定义 1 中,Dealer.ServiceCar<T> 采用类型 T 的参数。您正在将this传递到方法中,该方法的类型为 Car<T> 。您打算如何将Car<T>转换为Twhere约束只说TCar<T>,反之则不然。