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

本文关键字:泛型类型 实现 泛型接口 约束 何约束 | 更新日期: 2023-09-27 18:13:26

我正在开发一个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>而不需要在我的ApiClient类定义中定义T

编辑:

我想写:

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

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

您的类ApiClient甚至不使用ApiResource,因此您不能将ApiClientTCollection -Type约束为ApiResource的类型(不存在)。因此,我建议您为ApiClient设置与ApiResources相同的约束:

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

用法:

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

或者让你的方法泛型,像这样:

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>>();
但也许我完全弄错了你的问题。很难确定你到底想要达到什么。