是否有可能拥有一个对象列表,其参数具有不同的泛型/类型?

3
请考虑以下代码:

class Collision<type1, type2> 
{
    // further Code
}

有没有可能创建一个(比如)LinkedList<>,它的参数是通用的Collision?换句话说,我能否实现一个LinkedList<>,它接受任何参数的Collision对象?

public LinkedList< Collision<Unit, Unit> > collisionList = new LinkedList< Collision<Unit,Unit> >();

我采用了这种方法,使用基类Unit替代了两个子类PlayerEnemy。但是我还有一个Environment类,并不是子类,但也应该是Collision的可能参数。

提前感谢!


1
我认为你想要的是类似于 class MyClass : LinkedList<Collision<T, T>> 的东西。 - Vitor Canova
2个回答

6

一种方法是使用接口:

interface ICollision
{
    object PropertyOfType1{get;}
    object PropertyOfType2{get;}
}

然后是一个继承自该接口的通用类:

class Collision<type1,type2>:ICollision
{
    public type1 PropertyOfType1 {get;set;}
    public type2 PropertyOfType2 {get;set;}

    object ICollision.PropertyOfType1
    {
        get{return PropertyOfType1;}
    }

    object ICollision.PropertyOfType2
    {
        get{return PropertyOfType2;}
    }
}

然后,您可以使用界面创建您的链表:
LinkedList<ICollision> collisionList  = new LinkedList<ICollision>();

collisionList.AddLast(new Collision<int,int>());
collisionList.AddLast(new Collision<double,double>());

类似于我即将发布的答案,但并不完全相同。很好的回答。 - Greg
这是我认为更好的方法,比我的“对象”建议更可取。 - Christoph Fink

2
“Collection” 只能接受类型为 “T”、 “K” 或其子类的对象。如果 “Unit” 和 “Environment” 之间没有直接关系,您可以使用 “object”:
Collision<object, object>

要使“或其子项”起作用,您需要使用“covariance”:
interface ICollision<out T, out K> { }
class Collision<T, K> : ICollision<T, K> { }

然后制作一个列表,如下:
var collisionList = new LinkedList<ICollision<Unit, Unit>>();

您需要接口,因为类不支持协变,但是您可以将例如 Collision<Player, Enemy> 添加到列表中。

你确定吗?只能接受T、K或其子类的对象。 - Sriram Sakthivel
1
-1 类不支持协变!如果您编辑了误导性部分,将取消下投票。 - Sriram Sakthivel
如果我理解正确的话,那么除了先将参数类型强制转换为上层类,然后在以后使用时再将其转换回实际类型,没有其他选择了吧? - Acctubi
@user3293330:是的,但“向上转型”不需要强制转换。但请参考Albertos的答案,因为这比使用“object”更好。 - Christoph Fink

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接