返回一个泛型类型,它在c#中是一个集合

本文关键字:一个 集合 泛型类型 返回 它在 | 更新日期: 2023-09-27 17:49:42

我已经定义了一个可以以通用方式实现的接口。返回类型必须是一个集合,输入参数可以是一个类或值。

public interface IDataRetriever<T, C> where T : ICollection<string>
{
    T GetData(C criteria);
}

当我尝试返回List时,我得到一个错误"类型参数T不能与as操作一起使用,因为它没有类类型。"试着删除"as T",但这也不起作用。

如果我用List<string>替换T : ICollection<string>,它可以工作。这里有什么不对的地方?

public class CustomADataRetrieverImpl<T, C>: IDataRetriever<T, C> 
             where T : ICollection<string>
{
    public T GetData(C criteria)
    {
        string myCriteria = criteria as string;
        ICollection<string> data = new List<string>()
            ...
        return data as T;
    }
}

返回一个泛型类型,它在c#中是一个集合

as期望T是一个引用(或可空)类型,这意味着对class的约束也应该包含在您的签名中。

public interface IDataRetriever<T, C>
    where T : ICollection<string>, class
{
    T GetData(C criteria);
}

正如Jason在注释中提到的,如果T不是字符串类型或从T派生的类型,则返回null。但是,由于您的约束指定您希望ICollection<T>是字符串,因此这似乎是可以接受的,因为您的问题目前正在编写。

这不是你问的问题的答案,但值得注意的是,你似乎不理解as运算符。

criteria as string将返回null,除非typeof(C)已经是string,使得泛型没有价值。

同样,对于任何T,如果不是List<string>或从List<string>派生的类型,return data as T;将返回null。你可以考虑需要一个new()构造函数来允许你直接创建一个新的T

public class CustomADataRetrieverImpl<T, C>: IDataRetriever<T, C> 
             where T : ICollection<string>, new()
{
    public T GetData(C criteria)
    {
        string myCriteria = criteria.ToString();
        T data = new T()
            ...
        return data;
    }
}

如果你想修复TCList<string>string,你不需要使CustomADataRetrieverImpl通用:

public class CustomADataRetrieverImpl : IDataRetriever<List<string>, string>
{
    public List<string> GetData(string criteria)
    {
        var data = new List<string>();
        ...
        return data;
    }
}