Reputation: 6592
I have defined an interface that can be implemented in a generic way. The return type has to be a collection where as the input parameter can be a class or value.
public interface IDataRetriever<T, C> where T : ICollection<string>
{
T GetData(C criteria);
}
When I try to return a List I am getting an error "type parameter T cannot be used with the as operation because it does not have a class type." Tried removing the "as T" but that did not work either.
If I replace where T : ICollection<string>
with List<string>
it works. What is incorrect 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;
}
}
Upvotes: 3
Views: 100
Reputation: 33815
as
expects T to be a reference (or nullable) type, which means that a constraint to class should 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 will be returned. However, since your constraint specifies that you expect ICollection<T>
to be string, this seems acceptable as your question is currently written.
Upvotes: 4
Reputation: 144126
If you want to fix T
and C
to List<string>
and string
you don't need to make CustomADataRetrieverImpl
generic:
public class CustomADataRetrieverImpl : IDataRetriever<List<string>, string>
{
public List<string> GetData(string criteria)
{
var data = new List<string>();
...
return data;
}
}
Upvotes: 1
Reputation: 3785
Not the answer to the question you asked, but it's worth noting that you don't seem to understand the as
operator.
criteria as string
will return null unless typeof(C)
is already string
, making the generic worthless.
Likewise, return data as T;
will return null
for any T
that is not List<string>
or a type derived from List<string>
. You could consider requiring a new()
constructor to allow you to create a new T
directly.
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;
}
}
Upvotes: 2