すべての型の安全なenumに対してコンバーターを記述することなく、Stringを型安全なenumクラス(CountryIso)に変換するTypeConverterが必要です約作る。MCV環境で使用する汎用ジェネリックTypeConverterでInvalidCastExceptionが発生しました。
私は仕事に以下を得ることができますが:
CountryIso cI = (CountryIso) "1";
私はちょうどそれがジェネリックで動作させることはできません!次のサンプルは動作しませんが、なぜですか?
public class ExplicitCastConverter<T>: TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
// Always true: the type determines if a cast is available or not
return true;
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
String dummy = (String) value;
//CountryIso tst = (CountryIso) value; // Allowed, no problem casting
//CountryIso tst = (CountryIso) dummy; // Allowed, no problem casting
//var dum_001 = (T) ((String) value); // Does not compile
//var dumdum = (T) value; // Invalid case exception
//var hoot = (T) Convert.ChangeType(value, typeof (T)); // Invalid cast exception
return null;
}
}
プロバイダは次のとおりです。:
TypeDescriptor.AddProvider(new ExplicitCastDescriptionProvider<CountryIso>(), typeof(CountryIso));
var descriptor = TypeDescriptor.GetConverter(typeof(CountryIso));
var result = descriptor.ConvertFrom("1");
私は現在、汎用のTypeConverterの実装を持つ
//thanks: http://groups.google.com/group/wpf-disciples/browse_thread/thread/9f7bb40b7413fcd
public class ExplicitCastDescriptionProvider<T> : TypeDescriptionProvider //where T:TypeSafeEnum
{
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new ImplicitCastDescription<T>();
}
}
public class ImplicitCastDescription<T>: CustomTypeDescriptor //where T:TypeSafeEnum
{
public override TypeConverter GetConverter()
{
return new ExplicitCastConverter<T>();
}
}
私が持っているタイプセーフ列挙実装CountryIso(感謝StackOverflowの!):
public sealed class CountryIso: TypeSafeEnum
{
private static readonly Dictionary<int, CountryIso> InstanceDict = new Dictionary<int, CountryIso>();
public static readonly CountryIso NL = new CountryIso(1, "NL", "Netherlands");
public static readonly CountryIso BE = new CountryIso(2, "BE", "Belgium");
private CountryIso(int value, String name, String description): base(value,name,description)
{
InstanceDict.Add(value, this);
}
public static Dictionary<int, CountryIso> Instances
{
get { return new Dictionary<int, CountryIso>(InstanceDict); }
}
public static explicit operator CountryIso(String i)
{
int index;
return Int32.TryParse(i,out index) ? InstanceDict[index] : null;
}
}
TypeSafeEnumから継承
:
public class TypeSafeEnum
{
protected TypeSafeEnum(int value, String name, String description)
{
Name = name;
Value = value;
Description = description;
}
public int Value{ get; private set; }
public String Name { get; private set; }
public String Description { get; private set; }
}