How to convert to an object of a certain type?

N

Norbert Pürringer

Hello,

Imagine, that I've got a string variable containing a value of each
possible value type (string, int32, double, ...). Now I want to
convert the string to an object of the right type, where the correct
type is given by a Type variable.

So given is:
string strValue;
Type typeValue;

And I want to call something like
object value = Convert.ToType(strValue, typeValue);

Is there a simple way to do that?

Thank you,
Norbert
 
M

Marc Gravell

See below; Marc

string src = "12345";
Type dest = typeof(int);

// simple
int value1 = (int)Convert.ChangeType(src, dest);

// more versatile but more complex
// (and you might need to look at src->ConvertTo)
int value2 = (int)TypeDescriptor.GetConverter(dest).ConvertFrom(src);
 
N

Norbert Pürringer

Hi Marc,
string src = "12345";
Type dest = typeof(int);

// simple
int value1 = (int)Convert.ChangeType(src, dest);

// more versatile but more complex
// (and you might need to look at src->ConvertTo)
int value2 = (int)TypeDescriptor.GetConverter(dest).ConvertFrom(src);

That's good, thank you. Do you have an idea how to convert an array of
string into an array of a certain type given by a Type variable.
ChangeType only works for non array variables.

Thank you,
Norbert
 
M

Marc Gravell

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
 
N

Norbert Pürringer

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
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...

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
 
B

Ben Voigt [C++ MVP]

Marc said:
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.

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);
 
M

Marc Gravell

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);
});
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top