Returning a generic type that is a collection in C #

I have defined an interface that can be generically implemented. The return type must be a collection, where the input parameter can be a class or a value.

public interface IDataRetriever<T, C> where T : ICollection<string>
{

    T GetData(C criteria);
}

      

When I try to return a list, I get the error "The parameter type T cannot be used with the as operation because it does not have a class type." Tried deleting "like T" but that didn't work either.

If I replace T : ICollection<string>

with List<string>

, it works. What's wrong here?

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;
    }
}

      

+3


source to share


3 answers


as

expects T to be a reference (or null) type, which means that the class constraint must also be included in your signature.

public interface IDataRetriever<T, C>
    where T : ICollection<string>, class

{
    T GetData(C criteria);
}

      



As Jason mentioned in the comments, if T is anything other than a string type or a type derived from T, null is returned. However, since your constraint indicates what you expect to ICollection<T>

be a string, this seems acceptable since your question is currently being written.

+4


source


Not an answer to the question you asked, but it's worth noting that you don't seem to understand the operator as

.

criteria as string

will return null if typeof(C)

already string

, making generic useless.



Likewise, return data as T;

will return null

for any T

non- List<string>

or type derived from List<string>

. You could require a constructor new()

so that you can create a new one directly 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;
    }
}

      

+2


source


If you want to fix T

both C

before List<string>

and string

, you don't need to do CustomADataRetrieverImpl

generic:

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

      

0


source







All Articles