반사를 사용하여 문자열에서 nullable 로 변환
-
23-08-2019 - |
문제
반사를 사용하여 문자열에서 무효가 될 수있는 방법은 무엇입니까?
거의 모든 값이 주어진 거의 모든 값 유형으로 변환 할 다음 코드가 있습니다. issassignable wrom 등을 사용하기 위해이 위에는 약간의 코드가 있습니다. 그래서 이것은 마지막 수단입니다.
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());
}
문제는 긴처럼 무효 유형으로 변환하고 싶을 때 발생합니다.
분명히, 긴? 클래스에는 구문 분석 방법이 없습니다.
Nullable 's에서 구문 분석 방법을 어떻게 추출합니까? 주형 유형?
편집하다:
다음은 통과하려는 짧은 테스트 배터리입니다.
[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());
}
}
}
해결책 3
나는 이것을 조금 추가했다 :
if (Nullable.GetUnderlyingType(t) != null)
{
t = Nullable.GetUnderlyingType(t);
}
MethodInfo parse = t.GetMethod("Parse", new Type[] { typeof(string) });
모두 감사합니다!
다른 팁
나는 아마도 그것을 사용할 것입니다 TypeConverter
이 경우 그리고 ; 도중에 예제 ...Nullable.GetUnderlyingType()
static void Main()
{
long? val1 = Parse<long?>("123");
long? val2 = Parse<long?>(null);
}
static T Parse<T>(string value)
{
return (T) TypeDescriptor.GetConverter(typeof(T))
.ConvertFrom(value);
}
이것은 직업에해야합니다. (코드는 단순성을 위해 확장 방법에 포함되어 있지만 원하는 것이 아닐 수도 있습니다.)
public static T? ParseToNullable<T>(this string value) where T : struct
{
var parseMethod = typeof(T).GetMethod("Parse", new Type[] { typeof(string) });
if (parseMethod == null)
return new Nullable<T>();
try
{
var value = parseMethod.Invoke(null, new object[] { value.ToString() });
return new Nullable<T>((T)value);
}
catch
{
return new Nullable<T>();
}
}
이제 일반 유형 매개 변수를 원한다면 그 자체 근본적인 유형이 아닌 무효 유형이 되려면 (이것에서 실제로 이점을 보지 못합니다) : 당신은 다음을 사용할 수 있습니다.
Nullable.GetUnderlyingType(typeof(T))
Marc Gravell이 제안한 것처럼 코드에 대한 약간의 수정 만하면됩니다.
제휴하지 않습니다 StackOverflow