[英]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:在下面的示例中,当我从基础 class 调用ServiceCar
时,当该方法在 Dealer 中定义为:
Definition 1: ServiceCar<C>(C carToService) where C: Car<C>
.定义 1: ServiceCar<C>(C carToService) where C: Car<C>
。
But I do not get an error in the base Class when that method is defined in Dealer as:但是当该方法在 Dealer 中定义为:
Definition 2: ServiceCar<C>(Car<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;
}
}
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>
.我的困惑是微软说“其中 T: 表示类型参数必须是或派生自指定的基类”好吧,在定义 1(不编译)的情况下 C 是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?我收到的错误是“...无法从Car<T>
转换为 T”我错过了什么?
I think you a confusing different type parameters.我认为您混淆了不同的类型参数。 Class Car<T>
has parameter T
and method ServiceCar<C>
has another type parameter C
. Class Car<T>
有参数T
和方法ServiceCar<C>
有另一个类型参数C
。 So you need to specify both type parameters in the method and class declaration:所以你需要在方法和 class 声明中指定两个类型参数:
ServiceCar<C, T>(C carToService) where C : Car<T>
Off hand it looks like your confusing generics and inheritance.顺便说一下,它看起来像您令人困惑的 generics 和 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;
}
}
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
.您正在将Car<T>
类型的表达式传递给需要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
.它想要T
类型表达式的原因是因为Dealer.ServiceCar<T>
将C
显式定义为T
,因此carToService
参数必须是T
。
However, Car<T>
is not convertable to T
.但是, Car<T>
不能转换为T
。 Why should it be?为什么应该这样? It does not inherit from T
.它不继承自T
。 The only thing it inherits from is object
.它唯一继承的东西是object
。 Therefore, the compiler cannot convert an expression of type Car<T>
to an expression of type T
, just as indicated.因此,编译器无法将Car<T>
类型的表达式转换为T
类型的表达式,正如所示。
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
.需要明确的是,您站点的文档和您的 class 定义声明T
必须从Car<T>
继承,但它并没有说相反, Car<T>
必须从T
继承。
In definition 1, Dealer.ServiceCar<T>
takes a parameter of type T
.在定义 1 中, Dealer.ServiceCar<T>
采用T
类型的参数。 You are passing this
into the method, which is of type Car<T>
.您将其传递this
Car<T>
类型的方法。 How are you going to convert Car<T>
to T
?您将如何将Car<T>
转换为T
? The where
constraint only says T
is a Car<T>
, but not the other way around. where
约束只说T
是Car<T>
,反之则不然。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.