是否可以声明一个通用集合,以仅容纳使用任何<T>
实现通用接口的对象?
我的问题归结为:如果我想/必须存储实现通用接口的对象,那么与使用非通用集合或{{1}的通用)相比,有没有更好的方法来表达这一事实。
示例:
<Object>
这有可能吗?任何建议都将受到高度赞赏!
更新:新的,更详细的代码来阐明问题。
以下建议将通用接口基于非通用接口。但是结果是,通用接口的所有实现类都必须实现非通用方法,属性等。-还是可以解决吗?
感谢您的输入!
答案 0 :(得分:3)
是否可以声明一个通用集合以仅保存实现用 any
T
实例化的通用接口的对象?
简短回答:否。
更长的答案:不,因为那没有用。
让我们考虑一个简单的通用接口:
interface I<T> { T Get(); }
和一堆实现它的对象:
class Lion : I<Lion>
{
public Lion Get() => this;
}
class TaxPolicyFactory : I<TaxPolicy>
{
public TaxPolicy Get() => new TaxPolicy();
}
class Door: I<Doorknob>
{
public Doorknob Get() => this.doorknob;
...
}
好的,现在假设您有一个List<I<ANYTHING>>
,如您所愿:
var list = new List<I<???>> { new TaxPolicyFactory(), new Lion(), new Door() };
您有一个包含税收政策工厂,狮子和门的清单。这些类型没有什么共同点。您无法对每个对象执行任何操作。即使您可以分别对它们调用Get
,您也会有一个包含税收政策,狮子和门把手的序列,您将如何处理?
没有,就是那样。约束“对于任何I<T>
的实现接口T
”在C#中根本不是有用的约束,因此无法表达它。
听起来您遇到了“ XY”问题。在脑海中有一个不好的解决方案时,这是一个问题,现在您正在询问有关您的不好的解决方案的问题。 向我们询问有关您遇到的实际问题的信息,而不是关于解决方案的坏主意。真正的问题是什么?
更新:有了问题中的新信息,现在更加清楚了。您想要的功能称为通用接口协方差,这是我最喜欢的C#4功能。
如果您将界面定义更新为
interface ISyncInterface<out T> { ... }
然后,您可以在需要ISyncInterface<String>
的情况下使用ISyncInterface<Object>
。例如,您可以将ISyncInterface<Giraffe>
放入List<ISyncInterface<Animal>>
或其他任何内容中。
但是,您需要确保接口定义仅在协变有效位置使用T
。接口如所述有效,但是例如,如果您想向接口添加方法void M(T t);
,它将不再协变有效。 “ out”是一个助记符,告诉您T
只能用作方法的输出。由于IEnumerable<T>
也是协变有效的,所以很好; T
中没有IEnumerable<T>
的输入。
此外,差异仅适用于通用接口和委托,并且不同类型必须是引用类型。您不能将ISyncInterface<int>
放入List<ISyncInterface<Object>>
中,因为int
不是引用类型。
关于SO的协方差和协方差的帖子很多。您还应该阅读Microsoft文档。这可能是一个令人困惑的功能。如果您对我们设计和实现功能的历史细节感兴趣,请参阅我的博客。
答案 1 :(得分:0)
也许您可以尝试以下方法:
public interface MyInterface
{//methods common to all types
void FirstMethod();
}
public interface MyInterface<T> : MyInterface
{//methods specific to a type
void FirstMethod(T parameter);
}
public class MyClassThatHandlesAllInterfaces
{
private List<MyInterface> _allInterfacesT; //first interface in the chain
public void AddInterface<T>(MyInterface<T> ifToAdd)
{
_allInterfacesT.Add(ifToAdd); // <- this is what I'd like to do
}
}
我经常使用这种模式。因为我不知道有关您方案的所有详细信息,所以它可能不适合您。
但这可能会帮助其他人搜索Google。