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;
}
}
source to share
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.
source to share
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;
}
}
source to share
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;
}
}
source to share