tags:

views:

134

answers:

4

I would like to create a function that will return list of type that is specified by me at run time. I tried something along this line:

  public static List<T> GetMyList<T>(string[] itemList)
  {
     List<T>  resultList = new List<T>(itemList.Length);
     return resultList.AddRange(itemList);
  }

But this doesn't work. Obviously I don't fully understand how to pass a type to be converted to. Any help would be appreciated it.

Edit: It looks like that it is not possible, but here is more info. String array will contain numbers and I would like to convert those numbers sometimes into int, sometimes into short. Idea behind is to have a generic function that will attempt to convert items into whatever type list I tell it.

A: 

this doesn't work because system has no idea how to convert string to generic T. Also even if it is known, it will not work, because C# (prior to 4) doesn't have type covariance. So use either foreach to copy and convert elements one by one or use Select from Linq

Andrey
btw covariance works for arrays. but only if CLR can convert elements itseld, without conversion method
Andrey
+6  A: 

You need to provide a method to convert a string into a T - you can do this using a Func<string, T>:

public static List<T> GetMyList<T>(string[] itemList, Func<string, T> conversionFunc)
{
    return itemList.Select(conversionFunc).ToList();
}

e.g.

List<int> ints = GetMyList(new[] { "1", "2", "3" }, s => int.Parse(s));
Lee
How about List.ConvertAll instead of writing a new function? Eg. string[] itemArray = { "1", "2" }; (itemArray.ToList()).ConvertAll((x) => int.Parse(x));
Mads Ravn
+1  A: 

My first thought is that this won't work because not every object type can be constructed from a string. Perhaps you want something with a signature more like:

public static List<T> GetMyList<T>(T[] itemList)
{
  List resultList = new List(itemList.Length);
  foreach (t in itemList)
  {
    resultList.add(t);
  }
  return resultList;
}

(forgive my syntax. I don't have a compiler handy right now to check it.)

Al Crowley
A: 

Similar to Lee's but more generic...

public static class Tools
{
    public static List<TResult> ToList<T, TResult>(
       this IEnumerable<T> input,
            Func<T, TResult> conversion)
    {
        return input.Select(conversion).ToList();
    }
    public static List<TResult> ToList<T, TResult>(
        this IEnumerable<T> input,
             Func<T, int, TResult> conversion)
    {
        return input.Select(conversion).ToList();
    }
}

class Program
{
    static void Main(string[] args)
    {
        var input = new[] { "1", "2", "3" };

        var ret = input.ToList(i => int.Parse(i));
        // 1,2,3

        var ret2 = input.ToList((i,j) => int.Parse(i) + j * 10);
        // 1,12,23
    }
}
Matthew Whited
I was a little surprised that an overload for .ToList<T>() didn't match the above signature.
Matthew Whited