使用任何类型的通用类型收集类型

时间:2013-07-16 20:23:09

标签: c# generics collections types

我有这个问题我觉得可以通过多种方式解决,但我不确定最有效的方法是什么。同样的问题在collection of different generic types处被认定为SO,但似乎没有任何决议。我想重新提出这个问题并挑选专家的大脑!

在我的情况下,我有一份合同:

public interface IServiceInvoker<TServiceContract>
{
}

实际上还有一个抽象类可以集中管理一些核心代码,但是我不打算在这里包含它,这样问题就不会变得过于复杂。

TServiceContract类型可以是任何服务接口。因此,它不限于任何特定类型,因为实现类将验证服务等。然后,我将使用此类(下面的ServiceDAO)来封装此引用和其他引用的基本用法。我正在尝试创建IServiceInvoker类型的集合属性,但我没有运气......基本上我拥有的是:

public class ServiceDAO
{
    private Dictionary<string, object> _serviceInvocationCollection = new Dictionary<string, object>();

    public IEnumerable<KeyValuePair<string, object>> ServiceInvocationCollection
    {
        get { return _serviceInvocationCollection.AsEnumerable<KeyValuePair<string,object>>(); }
        private set { _serviceInvocationCollection = value as Dictionary<string, object>; }
    }
}

我宁愿该集合属于IServiceInvoker类型,但不能在类级别指定类型TServiceContract,因为集合可以使用任何实现IServiceInvoker类的数字...使用对象似乎过于松散打字...任何想法或建议表示赞赏!

2 个答案:

答案 0 :(得分:1)

简单方法

只需添加另一个非通用的界面:

public interface IServiceInvokerUntyped
{
}

public interface IServiceInvoker<TServiceContract> : IServiceInvokerUntyped
{
}

声明它的字典:

private Dictionary<string, IServiceInvokerUntyped> _serviceInvocationCollection = new Dictionary<string, IServiceInvokerUntyped>();

变体方法

如果您的泛型类型参数可以声明为协变:

public interface IServiceInvoker<out T> : IServiceInvokerUntyped
{
}

声明它的字典:

private Dictionary<string, IServiceInvoker<object>> _serviceInvocationCollection = new Dictionary<string, IServiceInvoker<object>>();

对于逆变,只需将'out'更改为'in'并根据需要修改字典声明/初始化。

答案 1 :(得分:1)

可能定义泛型继承自的基接口;然后你可以制作集合Dictionary<string, IServiceInvoker>

public interface IServiceInvoker { }
public interface IServiceInvoker<TServiceContract> : IServiceInvoker
{
}

或者,您可以为TServiceContract类型参数定义限制,例如IServiceContract,并使用Dictionary<string, IServiceInvoker<IServiceContract>>。但当然,每项服务都必须继承IServiceContract

public interface IServiceContract { }
public interface IServiceInvoker<TServiceContract>
    where TServiceContract : IServiceContract
{
}