Mi piacerebbe creare un TypeConverter
per una classe generica, come questo:Impossibile creare un TypeConverter per un tipo generico
[TypeConverter(typeof(WrapperConverter<T>))]
public class Wrapper<T>
{
public T Value
{
// get & set
}
// other methods
}
public class WrapperConverter<T> : TypeConverter<T>
{
// only support To and From strings
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
T inner = converter.ConvertTo(value, destinationType);
return new Wrapper<T>(inner);
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(System.String))
{
Wrapper<T> wrapper = value as Wrapper<T>();
TypeConverter converter = TypeDescriptor.GetConverter(typeof(T));
return converter.ConvertTo(wrapper.Value, destinationType);
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
Il problema arriva che non si può avere un generico in questa linea, è annullato:
[TypeConverter(typeof(WrapperConverter<T>))]
public class Wrapper<T>
Il mio prossimo approccio è stato quello di cercare di definire un unico convertitore, non generico in grado di gestire eventuali Wrapper<T>
istanze. Il mix di entrambi i riflessi e generici mi ha lasciato perplesso su come implementare sia i metodi ConvertTo
e ConvertFrom
.
Così, per esempio, il mio ConvertTo assomiglia a questo:
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(System.String)
&& value.GetType().IsGenericType)
{
// 1. How do I enforce that value is a Wrapper<T> instance?
Type innerType = value.GetType().GetGenericArguments()[0];
TypeConverter converter = TypeDescriptor.GetConverter(innerType);
// 2. How do I get to the T Value property? Introduce an interface that Wrapper<T> implements maybe?
object innerValue = ???
return converter.ConvertTo(innerValue, destinationType);
}
return base.ConvertTo(context, culture, value, destinationType);
}
In ConvertFrom
ho il più grande problema perché non ho modo di sapere quale classe wrapper per convertire le stringhe incomming in.
Ho creato diversi tipi di custome e TypeConverters da utilizzare con il framework API Web ASP.NET 4, ed è qui che devo utilizzarlo.
Un'altra cosa che ho provato è stata quella di assegnare la mia versione generica del convertitore in fase di esecuzione come visto here, ma il framework WebAPI non l'ha rispettato (cioè, il convertitore non è mai stato creato).
Un'ultima nota, sto usando .NET 4.0 e VS 2010.
Ho già risolto questo problema, credo di aver usato la dinamica per lanciare la T e anche per usare typeof. Dovrei poter pubblicare la mia soluzione domani, poiché non ho il codice accessibile in questo momento. – awright18
http://stackoverflow.com/questions/557340/c-sharp-generic-list-t-how-to-get-the-type-of-t Questo aiuta? – awright18
@ awright18 Grazie, ma non avevo quello di cui avevo bisogno. La mia domanda è principalmente come creare e associare un TypeConverter per un tipo generico. – tcarvin