繁体   English   中英

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

[英]Generic Type Constraint does not seem to be constraining anything

我在调用泛型方法时遇到了一些问题。 在下面的示例中,当我从基础 class 调用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;
      }
 }

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

我认为您混淆了不同的类型参数。 Class Car<T>有参数T和方法ServiceCar<C>另一个类型参数C 所以你需要在方法和 class 声明中指定两个类型参数:

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

顺便说一下,它看起来像您令人困惑的 generics 和 inheritance。 请记住其他开发人员在继承您的代码时可能需要做的事情。 我总是尽可能选择简单。

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;
      }
 }

尝试打电话时

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类型的表达式,正如所示。

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

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

暂无
暂无

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

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