を。それは基本的に、価値観や文化とのやりとりを行うクラスです。 TypeConverterとConvert.ChangeTypeの主な相違点は、TypeConvertersは任意のオブジェクトで動作することができますが、後でソースタイプでIConvertibleインターフェイスが必要になることです。
私はしばしばxmlファイルにさまざまな設定オブジェクトを保存するので、これのヘルパークラスを作成しました。これは、CultureInfo.InvariantCultureとの変換をハードコード化した理由です。
public static class TypeConversion {
public static Object Convert(Object source, Type targetType) {
var sourceType = source.GetType();
if (targetType.IsAssignableFrom(sourceType))
return source;
var sourceConverter = TypeDescriptor.GetConverter(source);
if (sourceConverter.CanConvertTo(targetType))
return sourceConverter.ConvertTo(null, CultureInfo.InvariantCulture, source, targetType);
var targetConverter = TypeDescriptor.GetConverter(targetType);
if (targetConverter.CanConvertFrom(sourceType))
return targetConverter.ConvertFrom(null, CultureInfo.InvariantCulture, source);
throw new ArgumentException("Neither the source nor the target has a TypeConverter that supports the requested conversion.");
}
public static TTarget Convert<TTarget>(object source) {
return (TTarget)Convert(source, typeof(TTarget));
}
}
それは実際のVersionオブジェクトにバージョン番号(「ABCD」)を含む文字列から同様の変換をサポートするために、(IConvertibleを実装doesntの)System.Versionのように、システムタイプを処理するために、独自のTypeConverterを作成するために完全に可能です。
public class VersionTypeConverter : TypeConverter {
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
if (sourceType == typeof(string))
return true;
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
var s = value as string;
if (s != null)
return new Version(s);
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
if (destinationType == typeof(string))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
var v = value as Version;
if (v != null && destinationType == typeof(string)) {
return v.ToString();
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
実際にカスタムTypeDescriptionProvider、およびtypeof(Version)
に渡し、TypeDescriptor.AddProviderを使用して、アプリケーションの起動時に、それを登録する必要があり、このプロバイダーを使用します。これはTypeDescriptorProvider.GetTypeDescriptorメソッドでカスタムCustomTypeDescriptorを返す必要があり、この記述子はGetConverterをオーバーライドしてVersionTypeConverterの新しいインスタンスを返す必要があります。簡単です。 ;)
Convert.ChangeTypeは、ソースが既に必要な型でない限り、IConvertibleを実装するためにソースオブジェクトを必要とします。 – sisve
XAttribute(XmlConvertのメソッドを使用)によってフォワード変換が行われているが、逆変換はConvertで行われる危険性はありますか?私は、変換が異なるかもしれないDateTimeのようなコーナーケースがあるかどうか分かりません。 –
はい!それは今のところ完璧に動作します。ありがとうございました!しかし、どうすればよいでしょうか?たとえば、私のメソッドを仮想クラスAで使用することはできません。そのためには、dintは文字列からの変換です。私が理解しているように、単に「どこでT:IConvertible」と指定する権利がないのであれば、十分な結果が得られません。 –