本文介绍了T&GT;仿制药&LT铸造;到特定的子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我有一类这样 公共类MyClass的< T>其中T:OneType {$ B $(B T)MyObj中获得{;组; } 公共MYCLASS(T OBJ) {} } 公共类亚纲:MyClass的< TwoType> {} //剪断其他类似的类定义 其中, TwoType 是 OneType 的。 现在,我有这样的工具方法 公共静态MyClass的< T>工厂< T>(T VD),其中T:OneType {开关(vd.TypeName) {情况下Constant.TwoType 返回新SubClass中((TwoType)VD); //剪断其他类型检查} } 它的功能是,很明显,检查 VD 的类型,并创建一个相应的 MyClass的键入。唯一的问题是,上面的代码将无法编译,我不知道为什么。 该错误是 不能施放的T表达TwoType 解决方案 由于Grzenio正确地指出,T类型的表达式无法转换为TwoType。编译器不知道表达是保证型TwoType - 这是由你的如果语句保证,但在分析类型时,编译器不会考虑if语句的含义。相反,编译器假定T可以是任何类型的满足约束,包括ThreeType,从OneType衍生但不是TwoType一个类型。显然,从ThreeType到TwoType没有转换,所以没有在T转换为TwoType无论是。 您可以通过说出好糊弄编译成允许它,对待T作为对象,然后把对象为TwoType。一路走来的每一步是合法的 - T是转换为对象,并且有可能是从对象TwoType转换,所以编译器允许它 您会然后得到了同样的问题,从SubClass中转换为 MyClass的< T> 。再次,可以通过铸造第一对象解决问题。 然而,这段代码仍然是错误的: 公共静态MyClass的< T>工厂< T>(T VD),其中T:OneType {开关(vd.TypeName) {情况下Constant.TwoType // WRONG 回报率(MyClass的< T>)(对象)(新的子类((TwoType)(对象)VD)); //剪断其他类型检查} } 为什么是错的?那么,考虑一切可能去错在这里。例如:你说 类AnotherTwoType:TwoType {} :X =出厂< TwoType> (新AnotherTwoType()); 会发生什么?我们不调用子类构造函数,因为参数是不完全型TwoType的,它是从TwoType派生的类型。而不是一个开关,你可能想 公共静态MyClass的< T>工厂< T>(T VD),其中T:OneType {如果(VD是TwoType) //还是错的回报率(MyClass的< T>) (对象)(新的子类((TwoType)(对象)VD)); //剪断其他类型检查} 这仍然是错误的。再次,想想可能出问题: X =工厂< OneType>(新TwoType()); 现在会发生什么?参数是TwoType,我们做一个新的子类,然后尝试将其转换为 MyClass的< OneType> ,但没有从SubClass中转化为 MyClass的< OneType> 所以这会崩溃,并在运行时死去 有关贵厂正确的代码 。 公共静态MyClass的< T>工厂< T>(T VD),其中T:OneType {如果(VD是TwoType&放大器;&安培; typeof运算(T)== typeof运算(TwoType))返回(MyClass的< T>)(对象)(新的子类((TwoType)(对象)VD)); //剪断其他类型检查} 是,现在全部清除?你可能会考虑不同的方法完全; 当你需要这么多的演员和运行时类型检查,以说服编译器代码是正确的,这就是证据,整个事情是一个糟糕的代码味道。 I have a class as suchpublic class MyClass<T> where T : OneType{ T MyObj { get; set; } public MyCLass(T obj) { }}public class SubClass: MyClass<TwoType>{}// snip for other similar class definitionwhere, TwoType is derived from OneType.Now, I have this utility methodpublic static MyClass<T> Factory<T>(T vd) where T : OneType{ switch(vd.TypeName) { case Constant.TwoType return new SubClass((TwoType)vd); // snip for other type check }}Which function is, obviously, checks the type of vd, and the creates an appropriate MyClass type. The only problem is the above code won't compile, and I don't know why The error is Cannot cast expression of T to TwoType 解决方案 As Grzenio correctly notes, an expression of type T is not convertible to TwoType. The compiler does not know that the expression is guaranteed to be of type TwoType -- that is guaranteed by your "if" statement, but the compiler does not consider the implication of the if statement when analysing types. Rather, the compiler assumes that T can be any type satisfying the constraint, including ThreeType, a type derived from OneType but not TwoType. Obviously there is no conversion from ThreeType to TwoType, and so there is no conversion from T to TwoType either.You can fool the compiler into allowing it by saying "well, treat the T as object, and then cast the object to TwoType". Every step along the way is legal -- T is convertible to object, and there might be a conversion from object to TwoType, so the compiler allows it.You'll then get the same problem converting from SubClass to MyClass<T>. Again, you can solve the problem by casting to object first.However, this code is still wrong:public static MyClass<T> Factory<T>(T vd) where T:OneType { switch(vd.TypeName) { case Constant.TwoType // WRONG return (MyClass<T>)(object)(new SubClass((TwoType)(object)vd)); // snip for other type check } } Why is it wrong? Well, consider everything that could go wrong here. For example: you sayclass AnotherTwoType : TwoType { }...x = Factory<TwoType>(new AnotherTwoType());What happens? We do not call the SubClass constructor because the argument is not exactly of type TwoType, it is of a type derived from TwoType. Instead of a switch, you probably wantpublic static MyClass<T> Factory<T>(T vd) where T:OneType { if (vd is TwoType) // STILL WRONG return (MyClass<T>)(object)(new SubClass((TwoType)(object)vd)); // snip for other type check } This is still wrong. Again, think about what could go wrong:x = Factory<OneType>(new TwoType());Now what happens? the argument is TwoType, we make a new SubClass, and then try to convert it to MyClass<OneType>, but there is no conversion from SubClass to MyClass<OneType> so this will crash and die at runtime.The correct code for your factory ispublic static MyClass<T> Factory<T>(T vd) where T:OneType { if (vd is TwoType && typeof(T) == typeof(TwoType)) return (MyClass<T>)(object)(new SubClass((TwoType)(object)vd)); // snip for other type check } Is that now all clear? You might consider a different approach entirely; when you need this many casts and runtime type checks to convince the compiler that the code is correct, that's evidence that the whole thing is a bad code smell. 这篇关于T&GT;仿制药&LT铸造;到特定的子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-10 12:12