ジェネリック型変換 FROM 文字列
-
08-06-2019 - |
質問
別のクラスの「プロパティ」を保存するために使用したいクラスがあります。これらのプロパティには名前と値があるだけです。理想的には、私が望むのは追加できることです タイプされた プロパティを使用して、返される「値」が常に希望するタイプになるようにします。
型は常にプリミティブである必要があります。このクラスは、基本的に名前と値を文字列として格納する抽象クラスをサブクラス化します。このサブクラスは、基本クラスに型安全性を追加する (変換の手間を省くだけでなく) という考えです。
そこで、(おおよそ)次のようなクラスを作成しました。
public class TypedProperty<DataType> : Property
{
public DataType TypedValue
{
get { // Having problems here! }
set { base.Value = value.ToString();}
}
}
そこで質問は次のとおりです。
文字列からプリミティブに変換する「一般的な」方法はありますか?
全体的に変換をリンクする汎用インターフェイスが見つからないようです(次のようなもの) ITryParsable 理想的だっただろう!)。
解決
あなたの意図を正しく理解したかどうかはわかりませんが、これが役立つかどうか見てみましょう。
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();}
}
}
他のヒント
lubos hasko のメソッドは null 許容値に対して失敗します。以下のメソッドは Nullable に対して機能します。でも思いつきませんでした。Google経由で見つけました: http://web.archive.org/web/20101214042641/http://dogaoztuzun.com/post/C-Generic-Type-Conversion.aspx 「Tuna Toksoz」の功績
最初の使用法:
TConverter.ChangeType<T>(StringValue);
クラスは以下です。
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)));
}
}
多くの型 (integer、double、DateTime など) に対して、静的な Parse メソッドがあります。リフレクションを使用して呼び出すことができます。
MethodInfo m = typeof(T).GetMethod("Parse", new Type[] { typeof(string) } );
if (m != null)
{
return m.Invoke(null, new object[] { base.Value });
}
TypeDescriptor.GetConverter(PropertyObject).ConvertFrom(Value)
TypeDescriptor
メソッドを持つクラスです GetConvertor
を受け入れる Type
オブジェクトを呼び出してから呼び出すことができます ConvertFrom
変換する方法 value
指定されたオブジェクトに対して。
次のような構成を使用できる可能性があります。 特性クラス. 。このようにして、文字列を独自の型の値に変換する方法を認識するパラメータ化されたヘルパー クラスが作成されます。その場合、ゲッターは次のようになります。
get { return StringConverter<DataType>.FromString(base.Value); }
ここで、パラメーター化された型に関する私の経験は C++ とそのテンプレートに限定されていると指摘しなければなりませんが、C# のジェネリックスを使用して同じようなことを行う方法があると思います。
静電気をチェックする Nullable.GetUnderlyingType
。- 基になる型が null の場合、テンプレート パラメータは Nullable
, 、そして、そのタイプを直接使用できます - 基礎となるタイプがnullでない場合は、変換で基礎となるタイプを使用します。
私にとってはうまくいくようです:
public object Get( string _toparse, Type _t )
{
// Test for Nullable<T> and return the base type instead:
Type undertype = Nullable.GetUnderlyingType(_t);
Type basetype = undertype == null ? _t : undertype;
return Convert.ChangeType(_toparse, basetype);
}
public T Get<T>(string _key)
{
return (T)Get(_key, typeof(T));
}
public void test()
{
int x = Get<int>("14");
int? nx = Get<Nullable<int>>("14");
}
public class TypedProperty<T> : Property
{
public T TypedValue
{
get { return (T)(object)base.Value; }
set { base.Value = value.ToString();}
}
}
オブジェクトを介した変換を使用しています。もう少し簡単です。
私はロボスアンサーを使用しましたが、うまくいきました。しかし、変換に問題がありました ダブルス 文化設定のせいで。それで私は追加しました
return (T)Convert.ChangeType(base.Value, typeof(T), CultureInfo.InvariantCulture);
さらに別のバリエーション。Nullable を処理するだけでなく、文字列が null で T が である状況も処理します。 ない null 可能。
public class TypedProperty<T> : Property where T : IConvertible
{
public T TypedValue
{
get
{
if (base.Value == null) return default(T);
var type = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
return (T)Convert.ChangeType(base.Value, type);
}
set { base.Value = value.ToString(); }
}
}
からのインスピレーションで、 ボブの答え、これらの拡張機能は、null 値の変換と、前後のすべてのプリミティブ変換もサポートしています。
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));
}
}
例
string stringValue = null;
int? intResult = stringValue.Convert<int?>();
int? intValue = null;
var strResult = intValue.Convert<string>();