如何创建包含开放通用接口的List <t>?</t>

时间:2010-12-23 18:50:57

标签: c# list generics interface

我有一个必须包含IInteract个对象的List。但IInteract是一个通用接口,需要2个类型参数。

我的主要想法是迭代一个对象列表,如果他们还没有进行交互,则互相“互动”。 所以我有这个对象

List<IObject> WorldObjects = new List<IObject>();

和这一个:

private List<IInteract> = new List<IInteract>();

除非我无法编译最后一行,因为IInteract需要2个类型参数。但是在我添加之前我不知道参数是什么。我可以在类型A的对象和A ...或类型B和C的对象之间添加交互。

我想创建“交互”类,它们使用“代理”对象和“目标”对象执行某些操作,但我希望它们独立于对象...所以我可以添加例如之间的交互。 .. “SuperUltraClass”和...... “整数”

我使用了错误的方法吗?

6 个答案:

答案 0 :(得分:3)

假设IInteract被定义为类似

interface IInteract<T1, T2>

并且您将它用于Foo类的字段:

class Foo
{
  List<IInteract...> field;
}

然后,如果你想推迟决定哪些类型绑定到IInteract类型的争论,你需要参数化容器类:

class Foo<T1, T2>
{
   List<IInteract<T1, T2>> field;
}

当您定义容器类的具体实例时,此处IInteract的类型参数将被绑定,例如:var x = new Foo<int, double>().这将导致IInteract字段的类型为IInteract<int, double>,用于该特定的实例化Foo泛型。

答案 1 :(得分:2)

我认为界面层次结构可能会使事情变得更容易。顶级可以是非泛型接口,只需要调用的方法,没有任何类型信息。第二级是那些需要打字的人......当然,仅仅拥有实现类而不是第二级接口就足够了。

public interface IInteract
{
    void Interact();
}

public interface IInteract<TActor,TTarget> : IInteract
{
    TActor Actor { get; set; }
    TTarget Target { get; set; }
}

然后,您可以创建IInteract对象列表,它可以包含任何强类型IInteract<TActor,TTarget>对象,但只有非通用接口上的那些方法才可用。重要的是具体的实现 - 这将决定什么代码被执行。

答案 2 :(得分:1)

我认为您应该使用inversion of control容器(过去我使用过Castle Windsor)。然后你可以做这样的事情:

void Interact<TA, TB>(TA objectA, TB objectB)
{
    var interact = Container.Resolve<IInteract<TA, TB>>();
    interact.Interact(objectA, objectB);
}

答案 3 :(得分:0)

我不确定我完全理解你想要完成的事情。您需要做的是创建一个实现您的界面的具体类,然后在List&lt;&gt;中使用它。像这样:

public interface IInteract
{
   Type A { get; set; }
   Type B { get; set; }
}


public class Interact : IInteract
{
    public Type A
    {
        get { return a; }
    }

    public Type B
    {
        get { return b; }
    }

}

然后在列表中使用您的具体类:

private List<Interact> = new List<Interact>();  

答案 4 :(得分:0)

你可以这样做:

private List<IInteract<SomeType, SomeOtherType>> = new List<IInteract<SomeType, SomeOtherType>>();

但就像你说的那样,你不知道你要添加什么类型。所以这里有几个选择:

1:使用object(或甚至dynamic)类型:

private List<IInteract<object, object>> ...

2:在班上使用泛型:

class Foo<T1, T2> {
    private List<IInteract<T1, T2>> ...
}

...

Foo<string, int> bar = new Foo<string, int>();

在第二个示例中,您将被锁定为仅将字符串和整数(或您创建Foo对象的任何内容)添加到列表中。在第一个示例中,您可以混合和匹配,但是您必须执行运行时类型检查以确定您从列表中删除的内容。

答案 5 :(得分:0)

您可能最好使用字典,其中键是您正在交互的两种类型的元组,值是Interact,因此每个Interact实现都必须进行一些转换

private Dictionary<Tuple<Type, Type>, IInteract<Object, Object>> interactions = new Dictionary<Tuple<Type, Type>, IInteract<Object, Object>>();

它有点乱,但你可以添加它:

IInteract<Object, Object> superClassIntInteraction = someInteractionClass;
interactions.Add(new Tuple<Type, Type>(typeof(SuperClass),typeof(int)), superClassIntInteraction);

我假设您希望能够搜索列表/字典以便稍后能够找到特定的交互,这就是字典派上用场的方式