return unknown Generic List<T>

76,580

Solution 1

Use IList instead of List<T>.

Solution 2

An alternative to being limited to returning a list of objects would be to either ensure that A and B derive from a common base type or implement a common interface, then return a list of that base type or interface. Include a constraint on the Generic method to that effect:-

List<ICommon> GetData<T>() where T: ICommon
{

}

Solution 3

You can't directly return a List<T> like this.

Why? Basically because List<A> and List<B> (or List<string> vs List<int> which is the same thing) are considered as 2 totally seperate unrelated classes.
Just as you can't return a string from a function which is declared to return int, you can't return a List of strings from a function which is declared to return a list of ints. The <T> here is a bit of a red herring. You couldn't write a generic method which returned both strings and ints either...

See here for more info on that kind of thing.

So what you have to do is return something that both types derive from (what they "have in common".)
As John Rasch says, you could return IList, (note the NON generic, so it's just a list of objects) or simply return it as an object. Unfortunately there is no way to preserve the type of the list.

Solution 4

Unless there's a specific reason that you can't specify the actual type ahead of time, you can just make the method itself generic:

public void Main() {
    List<A> a = GetData<A>();
}

public List<TType> GetData<TType>() {
     List<TType> list= new List<TType>();
     ...
     return list; 
}

Solution 5

You could do something like:

public void Main()
{
    List<int> a = GetData<int>();
    List<string> b = GetData<string>();
}

public List<T> GetData<T>()
{
    var type = typeof(T);
    if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
    {
        type = type.GenericTypeArguments[0];
    }

    if (type == typeof(int))
    {
        var a = new List<int> { 1, 2, 3 };
        return a.Select(v => v != null ? (T)Convert.ChangeType(v, type) : default(T)).ToList();
    }
    else if (type == typeof(string))
    {
        var b = new List<string> { "a", "b", "c" };
        return b.Select(v => v != null ? (T)Convert.ChangeType(v, type) : default(T)).ToList();
    }
}

Maybe you can modify that to your needs.

Share:
76,580
stevenrosscampbell
Author by

stevenrosscampbell

Updated on September 23, 2022

Comments

  • stevenrosscampbell
    stevenrosscampbell over 1 year

    and thanks for any assistance.

    How would I return from a method an unknown Generic.List type.

    public void Main()
    {
      List<A> a= GetData("A");   
    }
    
    public List<T> GetData(string listType)
    {
       if(listType == "A")
       {
         List<A> a= new List<A>() 
         ...
         return a; 
       }
       else
       {
         List<B> b = new List<B>()
         return b;
    
       }
    }
    

    In the below example I recieve an error similar to: Can't Convert List<A> to List<T>

    Is this possible? The error occurs on the 'return a;' line of code.
    Also, What will I need to do to make sure an error does not occur on the line:

    List<A> a= GetData("A");   
    

    Thanks, Steven