开发者

Generic Type Constraint does not seem to be constraining anything

I am having some issues surrounding the calling of a generic method. In the example below, when I call ServiceCar from the base class I get an error when that method is defined in Dealer as:

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

But I do not get an开发者_StackOverflow社区 error in the base Class when that method is defined in Dealer as:

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

My confusion is that Microsoft says that "where T: means the type argument must be or derive from the specified base class" Well in the case of definition 1 (which does not compile) C is Car<C>. So why isn't the type constraint parameter helping me out. The error I am getting reads "...cannot convert from Car<T> to T" What am I missing?


When attempting to call

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

with this

Dealer.ServiceCar<T>(this);

you are passing an expression of type Car<T> to a method that wants an expression of type T. The reason it wants an expression of type T is because Dealer.ServiceCar<T> is explicitly defining the C as T, so the carToService parameter must be a T.

However, Car<T> is not convertable to T. Why should it be? It does not inherit from T. The only thing it inherits from is object. Therefore, the compiler cannot convert an expression of type Car<T> to an expression of type T, just as indicated.

To be clear, the documentation that you site and your class definition states that T must inherit from Car<T>, but it does not say the inverse, that Car<T> must inherit from T.


I think you a confusing different type parameters. Class Car<T> has parameter T and method ServiceCar<C> has another type parameter C. So you need to specify both type parameters in the method and class declaration:

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


Off hand it looks like your confusing generics and inheritance. Keep in mind what other developers might have to do when they inherit your code. I always opt for simplicity when possible.

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


In definition 1, Dealer.ServiceCar<T> takes a parameter of type T. You are passing this into the method, which is of type Car<T>. How are you going to convert Car<T> to T? The where constraint only says T is a Car<T>, but not the other way around.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜