反射を使用して文字列からNullableに変換するにはどうすればよいですか?Reflectを使用して文字列からNullableに変換する<T>
ほとんどすべての値が指定されたほとんどすべての値型に変換する次のコードがあります。 IsAssignableFromなどを使用するには、このコードの上にかなりのコードがありますので、これが最後の手段です。
long型のnull型に変換したいときに問題が発生します。
明らかに、長い?クラスには解析メソッドがありません。
nullableのテンプレートタイプから解析メソッドを抽出するにはどうすればよいですか?
EDIT:
[Test]
public void ConverterTNullable()
{
Assert.That((int?)1, Is.EqualTo(Converter<int?>.Convert(1)));
Assert.That((int?)2, Is.EqualTo(Converter<int?>.Convert(2.0d)));
Assert.That(3, Is.EqualTo(Converter<long>.Convert(3)));
Assert.That((object)null, Is.EqualTo(Converter<long?>.Convert("")));
Assert.That((object)null, Is.EqualTo(Converter<long?>.Convert(null)));
Assert.That((object)null, Is.EqualTo(Converter<long?>.Convert(DBNull.Value)));
Assert.That((long)1, Is.EqualTo(Converter<long?>.Convert("1")));
Assert.That((long)2, Is.EqualTo(Converter<long?>.Convert(2.0)));
Assert.That((long?)3, Is.EqualTo(Converter<long>.Convert(3)));
}
全体の機能::
/// <summary>
/// Converts any compatible object to an instance of T.
/// </summary>
/// <param name="value">The value to convert.</param>
/// <returns>The converted value.</returns>
public static T Convert(object value)
{
if (value is T)
{
return (T)value;
}
Type t = typeof(T);
if (t == typeof(string))
{
if (value is DBNull || value == null)
{
return (T)(object)null;
}
else
{
return (T)(object)(value.ToString());
}
}
else
{
if (value is DBNull || value == null)
{
return default(T);
}
if (value is string && string.IsNullOrEmpty((string)value))
{
return default(T);
}
try
{
return (T)value;
}
catch (InvalidCastException)
{
}
if (Nullable.GetUnderlyingType(t) != null)
{
t = Nullable.GetUnderlyingType(t);
}
MethodInfo parse = t.GetMethod("Parse", new Type[] { typeof(string) });
if (parse != null)
{
object parsed = parse.Invoke(null, new object[] { value.ToString() });
return (T)parsed;
}
else
{
throw new InvalidOperationException("The value you specified is not a valid " + typeof(T).ToString());
}
}
}
[ValueString](https://github.com/safakgur/value-string)について私は、あなたが行ったように、反射を使って解析する方法を見つけるものを書きました。次に、それを呼び出すラムダ式を作成し、コンパイルされたデリゲートをキャッシュするので、同じタイプに解析される将来のコールにはそのオーバーヘッドはありません。 –