2009-06-24 2 views
0

문자열이 int, datetime, boolean, byte 등일 수 있습니다. '문자열의 유효성을 검사하는 방법은 특정 유형으로 변환 할 수 있습니까?

각 유형의 TryParse를 사용하지 않고 문자열을 해당 유형으로 변환 할 수 있는지 어떻게 확인할 수 있습니까?

+3

TryParse를 사용하지 않으려는 특별한 이유가 있습니까? 가장 쉽고, 가장 강력한 방법이며, 아마도 가장 빠른 방법 중 하나 일 것입니다. –

답변

3
public class GenericsManager 
{ 
    public static T ChangeType<T>(object data) 
    { 
     T value = default(T); 

     if (typeof(T).IsGenericType && 
      typeof(T).GetGenericTypeDefinition().Equals(typeof(Nullable<>))) 
     { 
      value = (T)Convert.ChangeType(data, Nullable.GetUnderlyingType(typeof(T))); 

     } 
     else 
     { 
      if (data != null) 
      { 
       value = (T)Convert.ChangeType(data, typeof(T)); 
      } 
     } 

     return value; 
    } 
} 

을하지 않을 경우 당신은 INT와 바이트 사이 differenciate해야하는 경우는 약간 난이도가 될 것입니다,하지만 난 당신이 이것을 사용할 수 있습니다 추측하고 검증 있지만 결과가 해당 유형의 기본값과 같지 않습니다.

그러나 tryparse는 현재 수행하려는 작업보다 훨씬 뛰어납니다.

+0

이것은 정확히 내가 찾던 솔루션 유형입니다. 어떤 방식으로, 나는 이미 내 사용하기에 더 호환 유사한 솔루션을 구현했습니다 : 개인 부울 IsTypeOf (문자열 값) 여기서 T : 구조체 { 경우 (string.IsNullOrEmpty (값)) 새로운 { 던져 ArgumentException ("텍스트는 null이거나 비어있을 수 없습니다.", value); } bool isFromType = false; 유형 type = typeof (T); MethodInfo tryParse = type.GetMethod ("TryParse", 새 유형 [] {typeof (string), type.MakeByRefType()}); if (tryParse! = null) { isFromType = (bool) tryParse.Invoke (null, new [] {value, null}); } return isFromType; } 감사합니다. – Tamir

+1

당신은 이것을 위해 반성을 사용하고 있습니까? 이 작업으로 무엇을 하려는지 모르겠지만 리플렉션은 몇 줄의 코드를 저장하는 데 사용할 수있는 값 비싼 프로세스입니다. 나는 거의 같은 체인지를 랩핑하는 것을 선호한다. try/catch (invalidcastexception) 블럭과 같은 것으로 메소드를 바꾼다. 내 머리 꼭대기에서 벗어나는 올바른 예외라고 생각하고, try/거기에서 흐름을 잡아라. - 완전히 잘 알고있는 것도 아닙니다. – tim

3

try catch 블록 (끔찍한 생각) 내에서 Parse()를 호출하는 것 외에, 유일한 대안은 자신의 구문 분석 알고리즘을 작성하는 것입니다 (나쁜 생각).

왜 TryParse 메서드를 사용하지 않으시겠습니까?

+0

나는 많은 가능한 유형이 있기 때문에 구문 분석/tryparsing을 사용하여 작성하는 코드가 많기 때문에이 추악한 방법을 사용하기 전에 더 나은 것을 찾고 있습니다. – Tamir

+0

if/else 문을 많이 사용한다고 생각합니다. 정말로 더 깨끗한 방법이 있다고 생각하지 않습니다. – AndrewS

1

정규식을 사용하여 어떤 유형인지 파악할 수 있습니다. 값이 여기에 대규모 유용 미만 255

0

TryParse과 정규식을 혼합하여 사용할 수 있습니다. 예쁜 코드는 아니지만 빠르며 어디서나이 메서드를 사용할 수 있습니다.

부울 유형에 관한 문제가 있습니다. 또는 은 부울 값을 나타낼 수 있지만 바이트에서도 올 수 있습니다. 사실을거짓으로 텍스트 값으로 파싱했지만 비즈니스 규칙과 관련하여 가장 적합한 것을 결정해야합니다.

public static Type getTypeFromString(String s) 
     { 
      if (s.Length == 1) 
       if (new Regex(@"[^0-9]").IsMatch(s)) return Type.GetType("System.Char"); 
      else 
       return Type.GetType("System.Byte", true, true); 

      if (new Regex(@"^(\+|-)?\d+$").IsMatch(s)) 
      { 
       Decimal d; 
       if (Decimal.TryParse(s, out d)) 
       { 
        if (d <= Byte.MaxValue && d >= Byte.MinValue) return Type.GetType("System.Byte", true, true); 
        if (d <= UInt16.MaxValue && d >= UInt16.MinValue) return Type.GetType("System.UInt16", true, true); 
        if (d <= UInt32.MaxValue && d >= UInt32.MinValue) return Type.GetType("System.UInt32", true, true); 
        if (d <= UInt64.MaxValue && d >= UInt64.MinValue) return Type.GetType("System.UInt64", true, true); 
        if (d <= Decimal.MaxValue && d >= Decimal.MinValue) return Type.GetType("System.Decimal", true, true); 
       } 
      } 

      if (new Regex(@"^(\+|-)?\d+[" + NumberFormatInfo.CurrentInfo.CurrencyDecimalSeparator + @"]\d*$").IsMatch(s)) 
      { 
       Double d; 
       if (Double.TryParse(s, out d)) 
       { 
        if (d <= Single.MaxValue && d >= Single.MinValue) return Type.GetType("System.Single", true, true); 
        if (d <= Double.MaxValue && d >= Double.MinValue) return Type.GetType("System.Double", true, true); 
       } 
      } 

      if(s.Equals("true",StringComparison.InvariantCultureIgnoreCase) || s.Equals("false",StringComparison.InvariantCultureIgnoreCase)) 
       return Type.GetType("System.Boolean", true, true); 

      DateTime dateTime; 
      if(DateTime.TryParse(s, out dateTime)) 
       return Type.GetType("System.DateTime", true, true); 

      return Type.GetType("System.String", true, true); 
     } 
관련 문제