我有一个必须包含IInteract
个对象的List。但IInteract
是一个通用接口,需要2个类型参数。
我的主要想法是迭代一个对象列表,如果他们还没有进行交互,则互相“互动”。 所以我有这个对象
List<IObject> WorldObjects = new List<IObject>();
和这一个:
private List<IInteract> = new List<IInteract>();
除非我无法编译最后一行,因为IInteract
需要2个类型参数。但是在我添加之前我不知道参数是什么。我可以在类型A的对象和A ...或类型B和C的对象之间添加交互。
我想创建“交互”类,它们使用“代理”对象和“目标”对象执行某些操作,但我希望它们独立于对象...所以我可以添加例如之间的交互。 .. “SuperUltraClass”和...... “整数”。
我使用了错误的方法吗?
答案 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);
我假设您希望能够搜索列表/字典以便稍后能够找到特定的交互,这就是字典派上用场的方式