데이터 변환을 시도하고 있습니다. 불행히도, 대부분의 데이터는 int 또는 double이어야하는 문자열에 있습니다 …
내가 가진 것은 다음과 같습니다.
double? amount = Convert.ToDouble(strAmount);
이 접근 방식의 문제점은 strAmount가 비어 있으면 비어 있으면 null이되기를 원하므로 데이터베이스에 추가하면 열이 null입니다. 그래서 나는 이것을 작성했다 :
double? amount = null;
if(strAmount.Trim().Length>0)
{
amount = Convert.ToDouble(strAmount);
}
이제는 잘 작동하지만 이제는 한 줄 대신 다섯 줄의 코드가 있습니다. 이것은 특히 변환 할 열이 많을 때 일을 읽기가 더 어려워집니다.
나는 문자열 클래스에 대한 확장을 사용하고 타입을 전달하기 위해 generic을 확장한다고 생각했다. 이것은 double, int 또는 long 일 수 있기 때문이다. 그래서 나는 이것을 시도했다 :
public static class GenericExtension
{
public static Nullable<T> ConvertToNullable<T>(this string s, T type) where T: struct
{
if (s.Trim().Length > 0)
{
return (Nullable<T>)s;
}
return null;
}
}
그러나 오류가 발생합니다 : ‘string’유형을 ‘T’로 변환 할 수 없습니까?
이 주위에 방법이 있습니까? 제네릭을 사용하여 메서드를 만드는 데 익숙하지 않습니다.
답변
명심해야 할 또 다른 사항은 문자열 자체가 null 일 수 있다는 것입니다.
public static Nullable<T> ToNullable<T>(this string s) where T: struct
{
Nullable<T> result = new Nullable<T>();
try
{
if (!string.IsNullOrEmpty(s) && s.Trim().Length > 0)
{
TypeConverter conv = TypeDescriptor.GetConverter(typeof(T));
result = (T)conv.ConvertFrom(s);
}
}
catch { }
return result;
}
답변
아래 확장 방법을 사용해보십시오.
public static T? GetValueOrNull<T>(this string valueAsString)
where T : struct
{
if (string.IsNullOrEmpty(valueAsString))
return null;
return (T) Convert.ChangeType(valueAsString, typeof(T));
}
이 방법으로 할 수 있습니다 :
double? amount = strAmount.GetValueOrNull<double>();
int? amount = strAmount.GetValueOrNull<int>();
decimal? amount = strAmount.GetValueOrNull<decimal>();
답변
이건 어때?
double? amount = string.IsNullOrEmpty(strAmount) ? (double?)null : Convert.ToDouble(strAmount);
물론 이것은 변환 실패를 고려하지 않습니다.
답변
이 제네릭 형식 변환기를 작성했습니다. Nullable 및 표준 값과 함께 작동하며 문자열뿐만 아니라 모든 컨버터블 유형 간을 변환합니다. 예상되는 모든 종류의 시나리오 (기본값, null 값, 기타 값 등)를 처리합니다.
나는 이것을 수십 개의 프로덕션 프로그램에서 약 1 년 동안 사용해 왔으므로 꽤 견고해야합니다.
public static T To<T>(this IConvertible obj)
{
Type t = typeof(T);
if (t.IsGenericType
&& (t.GetGenericTypeDefinition() == typeof(Nullable<>)))
{
if (obj == null)
{
return (T)(object)null;
}
else
{
return (T)Convert.ChangeType(obj, Nullable.GetUnderlyingType(t));
}
}
else
{
return (T)Convert.ChangeType(obj, t);
}
}
public static T ToOrDefault<T>
(this IConvertible obj)
{
try
{
return To<T>(obj);
}
catch
{
return default(T);
}
}
public static bool ToOrDefault<T>
(this IConvertible obj,
out T newObj)
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = default(T);
return false;
}
}
public static T ToOrOther<T>
(this IConvertible obj,
T other)
{
try
{
return To<T>(obj);
}
catch
{
return other;
}
}
public static bool ToOrOther<T>
(this IConvertible obj,
out T newObj,
T other)
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = other;
return false;
}
}
public static T ToOrNull<T>
(this IConvertible obj)
where T : class
{
try
{
return To<T>(obj);
}
catch
{
return null;
}
}
public static bool ToOrNull<T>
(this IConvertible obj,
out T newObj)
where T : class
{
try
{
newObj = To<T>(obj);
return true;
}
catch
{
newObj = null;
return false;
}
}
답변
시도해 볼 수 있습니다.
TypeConverter conv = TypeDescriptor.GetConverter(typeof(int));
conv.ConvertFrom(mystring);
자신의 null 검사를 수행하고 int?
필요한 경우 반환 하십시오. 당신은 또한 그것을try {}
답변
이 기회를 …
public delegate bool TryParseDelegate<T>(string data, out T output);
public static T? ToNullablePrimitive<T>(this string data,
TryParseDelegate<T> func) where T:struct
{
string.IsNullOrEmpty(data) return null;
T output;
if (func(data, out output))
{
return (T?)output;
}
return null;
}
그럼 이렇게 불러
void doStuff()
{
string foo = "1.0";
double? myDouble = foo.ToNullablePrimitive<double>(double.TryParse);
foo = "1";
int? myInt = foo.ToNullablePrimitive<int>(int.TryParse);
foo = "haha";
int? myInt2 = foo.ToNullablePrimitive<int>(int.TryParse);
}
답변
나는 Joel의 대답을 좋아하지만 예외를 먹는 팬이 아니기 때문에 약간 수정했습니다.
/// <summary>
/// Converts a string to the specified nullable type.
/// </summary>
/// <typeparam name="T">The type to convert to</typeparam>
/// <param name="s">The string to convert</param>
/// <returns>The nullable output</returns>
public static T? ToNullable<T>(this string s) where T : struct
{
if (string.IsNullOrWhiteSpace(s))
return null;
TypeConverter conv = TypeDescriptor.GetConverter(typeof (T));
return (T) conv.ConvertFrom(s);
}
/// <summary>
/// Attempts to convert a string to the specified nullable primative.
/// </summary>
/// <typeparam name="T">The primitive type to convert to</typeparam>
/// <param name="data">The string to convert</param>
/// <param name="output">The nullable output</param>
/// <returns>
/// True if conversion is successfull, false otherwise. Null and whitespace will
/// be converted to null and return true.
/// </returns>
public static bool TryParseNullable<T>(this string data, out T? output) where T : struct
{
try
{
output = data.ToNullable<T>();
return true;
}
catch
{
output = null;
return false;
}
}