If you know the destination type at compile-time (perhaps via generics),
the following works:
string[] data = {"12345", "3154", "15012"};
// C# 2 (VS2005)
int[] values1 = Array.ConvertAll<string, int>(data,
delegate(string value)
{ // of your chosen method from last post...
return int.Parse(value);
});
// C# 3 (VS2008)
int[] values = Array.ConvertAll(data, value =>
int.Parse(value));
Again - you would be able to use this with generics (T[], etc). If you
don't know the type (and generics aren't available), you could either
use an object[], or ues Array.CreateInstance to create an array (of
cited type), then loop over it setting values.
My first choice would be: refactor the code so that you can use
generics. Hard to say "how" without more detail...
Marc
Norbert Pürringer - 28 Apr 2008 14:36 GMT
Hi Marc,
> Again - you would be able to use this with generics (T[], etc). If you
> don't know the type (and generics aren't available), you could either
[quoted text clipped - 3 lines]
> My first choice would be: refactor the code so that you can use
> generics. Hard to say "how" without more detail...
I would like use generics, but how???
I've got a Type variable, e.g.
Type type = typeof(System.Int32);
How can I instantiate a generic list using that type variable?
List<type> list = new List<type>();
does not work. The compiler needs something like that:
List<Int32> list = new List<Int32>();
That's static. I need a dynamic way. Any idea?
Kind regards,
Norbert
Marc Gravell - 28 Apr 2008 14:54 GMT
You can use reflection to invoke the generic method dynamically:
using System;
using System.ComponentModel;
using System.Reflection;
static class Program
{
static void Main()
{
string[] values = {"12345", "123", "5142"};
foreach (int value in CreateData(typeof(int), values))
{
Console.WriteLine(value);
}
}
// get the method-template (i.e. this points to CreateData<T>, but
without the "T" yet)
private static readonly MethodInfo genericMethod =
typeof(Program).GetMethod("CreateData", BindingFlags.NonPublic
| BindingFlags.Static,
null, new Type[] { typeof(string[]) }, null);
// actually returns an array of the correct type, but arrays are
covariant
static Array CreateData(Type destinationType, string[] values)
{
// invoke the generic method (after supplying a specific "T")
object[] args = { values };
return
(Array)genericMethod.MakeGenericMethod(destinationType).Invoke(null, args);
}
static T[] CreateData<T>(string[] values)
{
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
return Array.ConvertAll<string, T>(values, delegate(string val)
{
return (T)converter.ConvertFrom(val);
});
}
}
Ben Voigt [C++ MVP] - 28 Apr 2008 14:48 GMT
> If you know the destination type at compile-time (perhaps via
> generics), the following works:
[quoted text clipped - 14 lines]
> use an object[], or ues Array.CreateInstance to create an array (of
> cited type), then loop over it setting values.
You could do this, however I would expect it to be very slow because it has
to re-test the destination type and re-plan the conversion for each element.
Array dest = Array.CreateInstance(t, src.Length);
Array.ConvertAll<string, object>(delegate (string value) {
Convert.ChangeType(value, t); }).CopyTo(dest, src.Length);
> My first choice would be: refactor the code so that you can use
> generics. Hard to say "how" without more detail...
>
> Marc