Problem
I’d like to utilize a class to hold “properties” for another class. The only thing these attributes have is a name and a value. In an ideal world, I’d like to be able to add typed properties to ensure that the “value” provided is always of the type I specify.
A primitive type should always be used. This class is a subclass of an abstract class that saves the name and value of a variable as a string. The assumption is that this subclass will give the base class some type safety (as well as saving me on some conversion).
As a result, I’ve constructed a class that looks like this (roughly):
public class TypedProperty<DataType> : Property
{
public DataType TypedValue
{
get { // Having problems here! }
set { base.Value = value.ToString();}
}
}
So, here’s the query:
Is there a “universal” technique to convert a primitive back to a string?
I haven’t been able to find a common interface that connects all of the conversions (something like ITryParsable would have been excellent!).
Asked by Rob Cooper
Solution #1
I’m not sure if I really comprehended your aims, but let’s see if this one helps.
public class TypedProperty<T> : Property where T : IConvertible
{
public T TypedValue
{
get { return (T)Convert.ChangeType(base.Value, typeof(T)); }
set { base.Value = value.ToString();}
}
}
Answered by lubos hasko
Solution #2
For nullables, lubos Hasko’s technique fails. For nullables, use the procedure below. I didn’t think of it, though. I discovered it using Google: http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx “Tuna Toksoz” deserves credit.
Usage first:
TConverter.ChangeType<T>(StringValue);
The course is listed below.
public static class TConverter
{
public static T ChangeType<T>(object value)
{
return (T)ChangeType(typeof(T), value);
}
public static object ChangeType(Type t, object value)
{
TypeConverter tc = TypeDescriptor.GetConverter(t);
return tc.ConvertFrom(value);
}
public static void RegisterTypeConverter<T, TC>() where TC : TypeConverter
{
TypeDescriptor.AddAttributes(typeof(T), new TypeConverterAttribute(typeof(TC)));
}
}
Answered by Tim Coker
Solution #3
There is a static Parse method for several types (integer, double, DateTime, and so on). You can use reflection to call it up:
MethodInfo m = typeof(T).GetMethod("Parse", new Type[] { typeof(string) } );
if (m != null)
{
return m.Invoke(null, new object[] { base.Value });
}
Answered by dbkk
Solution #4
TypeDescriptor.GetConverter(PropertyObject).ConvertFrom(Value)
TypeDescriptor is a class that has a method called GetConvertor that accepts a Type object and then calls the ConvertFrom method to convert the value for that object.
Answered by Dinesh Rathee
Solution #5
These modifications, inspired by Bob’s response, additionally support null value conversion and all primitive conversion back and forth.
public static class ConversionExtensions
{
public static object Convert(this object value, Type t)
{
Type underlyingType = Nullable.GetUnderlyingType(t);
if (underlyingType != null && value == null)
{
return null;
}
Type basetype = underlyingType == null ? t : underlyingType;
return System.Convert.ChangeType(value, basetype);
}
public static T Convert<T>(this object value)
{
return (T)value.Convert(typeof(T));
}
}
Examples
string stringValue = null;
int? intResult = stringValue.Convert<int?>();
int? intValue = null;
var strResult = intValue.Convert<string>();
Answered by Ghominejad
Post is based on https://stackoverflow.com/questions/8625/generic-type-conversion-from-string