2011-06-29 170 views
1

我有一些问题围绕着调用泛型方法。在下面的示例中,当我从基类中调用ServiceCar时,在经销商中定义该方法时出现错误:泛型类型约束似乎没有约束任何东西

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

但是,当该方法在经销商被定义为我没有得到在基类中的错误:

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

我的困惑是,微软says“凡T:意味着类型参数必须是或从指定的基类派生的“在定义1(不编译)的情况下,C是Car<C>。那么为什么不是类型约束参数帮助我。我得到的错误读取“...不能从Car<T>转换到T”我缺少什么?

回答

1

当试图调用

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

与此

Dealer.ServiceCar<T>(this); 

你逝去的Car<T>类型的表达式来想要T类型的表达的方法。因为Dealer.ServiceCar<T>明确定义CT,所以carToService参数必须是T

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

要清楚,你的网站和你的类定义指出T必须从Car<T>继承的文件,但它并没有说的倒数,即Car<T>必须从T继承。

1

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

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

副手它看起来像您混淆的泛型和继承。请记住其他开发人员在继承代码时可能必须执行的操作。如果可能,我总是选择简单。

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

我知道这不是一个理想的样本,有更好的方法来做到这一点。我只是试图找到一种方法来从基类和继承类调用相同的泛型方法。 –

+0

哦,好的。你可以试试这个,然后'public static void ServiceCar (C carToService)where C:Car'然后从你的基类中移除泛型定义。 – Jay

0

在定义1,Dealer.ServiceCar<T>需要T类型的参数。您正将this传入方法,该方法的类型为Car<T>。你打算如何将Car<T>转换为Twhere约束条件只表示TCar<T>,但不是相反。