C#将派生的泛型类型转换为父类

时间:2015-10-04 00:07:20

标签: c# generics downcast

在我提出问题之前,这是我的结构:

State:<tab>S (sleeping)

当我创建public class Data : ScriptableObject {...} public class ItemData : Data {...} public class WeaponData : ItemData {...} public abstract class Item<T> : Visual<T> where T : ItemData {...} public class Weapon<T> : Item<T> where T : WeaponData {...} 对象并将其分配给Weapon时,我收到错误(无法从源类型转换为目标类型)。

Item<ItemData>

为什么?

2 个答案:

答案 0 :(得分:5)

在C#中,协方差(将派生类型分配给基本类型)不能应用于泛型类。因此,您需要在新的IItem接口上使用out parameter modifier来应用专门标记为协变的接口。

然而,这本身并不足够。当Item具有可能 的泛型类型参数时,您无法告诉Weapon它将允许Weapon的实例分配给它ItemData任何 ,只要它继承自IItemData。这使编译器陷入困境,因为它无法保证关系是有效的。但是,如果您将新的ItemData界面应用于void Main() { Weapon<Foo> weapon = new Weapon<Foo>(); IItem<ItemData> other = weapon; } public interface IItem<out T> {} public interface IItemData {} public class Foo : WeaponData {} public class Data : ScriptableObject {} public class ItemData : Data, IItemData {} public class WeaponData : ItemData {} public abstract class Item<T> : Visual<T>, IItem<T> where T : IItemData {} public class Weapon<T> : Item<T> where T : WeaponData {} public class ScriptableObject {} public class Visual<T> {} ,则可以允许演员。

Item<T>

这需要将IItemData更新为约束为select 6371 * acos( cos( radians(1.5378236000) ) * cos( radians( 1.5395056000 ) ) * cos( radians( 1.5378236000 ) - radians(110.3373156000) ) + sin( radians(1.5378236000) ) * sin( radians( 1.5395056000 ) ) ) AS dis1, GetDistance(1.5378236000, 110.3372347000, 1.5395056000, 110.3373156000) as dis2 ,而不是限制为具体类型。

答案 1 :(得分:0)

当你处理这类东西时,泛型变得非常奇怪。我没有在C#中对此进行过调查,但是如果它像Java那样 - 我怀疑它是 - 如果泛型参数匹配,你只能设置给定泛型类型的变量。例如,其他必须是Foo类型的项目Item<Foo>),而不是类型ItemData。原因是这样的:

class A {...}
class B : A {...}
class C {
    public static void main(string[] args) {
        List<B> BL = new List<B>();
        List<A> AL = BL;
        AL.Add(new A()); // Now the List of B instances has an A instance in it!!
    }
}

我不确定是否可以使用C#中的Java List<? extends A>这样的方法。这将是Java类型的解决方案。