如何约束泛型类型以实现通用接口?

时间:2014-07-18 15:33:36

标签: c# generics

我正在开发一个API的C#库,简化如下:

// GET /foos
{
  "data": [
    { FooResource },
    { Fooresource },
    ...
  ]
}
// GET /bars
{
  "data": [
    { BarResource },
    { BarResource },
    ...
  ]
}

我希望我的库的用户能够指定他们想要使用的通用集合。到目前为止,非常好。

class ApiResources<T, TCollection> where TCollection : ICollection<T>
{
    public TCollection Data { get; set; }
}

但是,我希望在实例化客户端单例时指定它(在这种情况下,IFooIBar是定义Foo和Bar资源中各种键的接口)

class ApiClient<TFoo, TBar, TCollection>
  where TFoo : IFoo
  where TBar : IBar
  where TCollection : ???
{
    TCollection<TFoo> GetFoos()
    {
        ApiResources<TFoo, TCollection> resources = // make API call to get Foos
        return resources.Data;
    }

    TCollection<TBar> GetBars()
    {
        ApiResources<TBar, TCollection> resources = // make API call to get Bars
        return resources.Data;
    }
}

我该怎么做呢? 我收到了There is no boxing conversion or type parameter conversion from 'TCollection' to 'ICollection<TFoo>'个错误。我基本上想要TCollection : ICollection<T>而不需要在我的T类定义中定义ApiClient

编辑:

我希望能写下来:

var client = new ApiClient<Foo, Bar, List>(); // List<T> for any T???
List<Foo> foos = client.GetFoos();
List<Bar> bars = client.GetBars();

1 个答案:

答案 0 :(得分:0)

您的班级ApiClient甚至无法使用ApiResource,因此您无法将TCollection - ApiClient的类型限制为ApiResource的类型1}}(不存在)。因此,我建议您为ApiClient制定ApiResources的相同约束:

class ApiClient<TFoo, TBar, T, TCollection> [...] where TCollection : ICollection<T>

用法:

var x = new ApiClient<Foo, Bar, SomeClass, Collection<SomeClass>>().GetFoos();

或者你制作methods generic,就像这样:

TCollection GetFoos<T, TCollection> where T : TFoo where TCollection : ICollection<T>()
{
    ApiResources<TFoo, TCollection> resources = // make API call to get Foos
    return resources.Data;
}

用法:

var x = new ApiClient<Foo, Bar>().GetFoos<SomeClass, Collection<SomeClass>>();

但也许我的问题完全错了。很难确定你想要达到什么目标。