2011-11-14 5 views
9

사용자 입력 데이터의 유효성을 검사하고 런타임에 지정된 유형으로 문자열 값을 변환 할 수 있도록해야합니다. 반드시 실제 변환을 수행 할 필요는 없으며 입력 값이 유효한지 테스트해야합니다. 이런 유형의 평가를 수행 할 클래스 또는 메소드를 찾지 못했습니다. 그러나 누락 된 사항이 있으면 알려주십시오. 사용할 수있는 특정 버전의 솔루션이 있으면 C# 4.0으로 작업하고 있습니다.C#에서 문자열을 주어진 유형으로 변환 할 수 있는지 확인하십시오.

이 메서드는 "표준"형식 (기본 제공 값 데이터 형식과 String) 만 처리하면됩니다. 평가할 필요가있는 유일한 사용자 정의 유형은 라이브러리에 정의 된 특정 enum 유형입니다.

나는 현재 무게를 측정하고 있지만 둘 다 완벽하지 않기 때문에 3 번째 옵션 (또는 내가 놓친 프레임 워크에 내장 된 것)이 있었으면합니다. 솔루션 # 1에서 try-catch를 사용하면 문제가있는 것 같아서 솔루션 # 2쪽으로 크게 기울고 있습니다.

해결 방법 1 : Convert.ChangeType() 시도/캐치

public Boolean CheckType(String value, Type type) 
{ 
    try 
    { 
     var obj = Convert.ChangeType(value, type); 
     return true; 
    } 
    catch(InvalidCastException) 
    { 
     return false; 
    } 
    catch(FormatException) 
    { 
     return false; 
    } 
    catch(OverflowException) 
    { 
     return false; 
    } 
    catch(ArgumentNullException) 
    { 
     return false; 
    } 
} 

해결 방법 2 경우이 방법도 수백 또는 호출 할 수

public Boolean CheckType(String value, Type type) 
{ 
    if (type == typeof(String)) 
    { 
     return true; 
    } 
    else if (type == typeof(Boolean)) 
    { 
     Boolean b; 
     return Boolean.TryParse(value, out b); 
    } 
    else if (type == typeof(Int32)) 
    { 
     Int32 i; 
     return Int32.TryParse(value, out i); 
    } 
    else if (type == typeof(Int64)) 
    { 
     Int64 l; 
     return Int64.TryParse(value, out l); 
    } 
    // similar code to check all other types 
    // (Int16, UInt32, UInt64, UInt16, Byte, SByte, Single, Double, Decimal, 
    // Enum, Char, DateTime) 
    . 
    . 
    . 
    . 
    . 
    else 
     throw new ArgumentException("Invalid type evaluation"); 

} 

/다른 유형 검사 체인 및 TryParse 입력 데이터가 심각하게 엉망이거나 손상된 경우 짧은 간격으로 수천 번 반복되므로 반복되는 if/else 검사가 performa에 대한 드래그가 될지 걱정됩니다. nce (필자는이 시점에서 반드시 최적화하려고하지 않고 다른 옵션을 고려해야 함).

두 솔루션에서 내가 가진 다른 문제는 실제로 예상되는 형식의 새 값으로 문자열 값을 변환하고 두 경우 모두 결과를 삼키는 것입니다.

+0

@JeremyMcGee 난 당신이 링크 된 질문을보고 있지만, 실제로 값을 변환 할 찾고 있지 않다 때문에, 그냥 변환 할 수있는, 내 질문은 반드시 중복 생각하지 않았다 테스트합니다. – psubsee2003

+0

@ psubsee2003 : 무언가를 변환 할 수 있는지, 실제로 변환 할 수 있는지를 확인하는 노력은 일반적으로 매우 적습니다. – Joe

+0

@Joe 필자는 그럴듯한 느낌이 들었지만 TryParse 메서드가 명백한 예외없이 매우 빠르기 때문에 변환하기 전에 먼저 확인해야 할 방법이 있는지 궁금해하고있었습니다. – psubsee2003

답변

3

MSDN 문서를 기반으로 자신의 오류 처리를 추가하십시오.

+0

결국에는 TypeConverter 응답에 예외 처리가 필요하므로이 권장 사항과 함께갔습니다. 피하기 위해. – psubsee2003

14

TypeConverter 및 일반적인 방법을 사용하는 것이 좋습니다. 이렇게하면 많은 if 문을 피할 수 있습니다. 예외가 비싼 (성능)이기 때문에, 나는 TryParse 웨이를 선호

class Program 
    { 
     static T convert<T>(string s) 
     { 
      var typeConverter = TypeDescriptor.GetConverter(typeof(T)); 
      if (typeConverter != null && typeConverter.CanConvertFrom(typeof(string))) 
      { 
       return (T) typeConverter.ConvertFrom(s); 
      } 

      return default(T); 
     } 

     static void Main(string[] args) 
     { 
      int x = convert<int>("45"); 
     } 
    } 
+0

이것이 유형을 검사하는 원래의 문제가 어떻게 해결되는지는 잘 모르겠다. 잘못된 값을 변환기에 전달하면 (예 : int에 대해 "14.1") FormatException이 throw됩니다. 내 첫 번째 해결책은 이미 그렇게했기 때문에 이것이 바람직한 이유가 확실하지 않습니다. – psubsee2003

+2

메서드가 일반적이고 추가하는 모든 새 형식에 ** 블록 **이 필요하지 않기 때문에 바람직합니다 –

11

나는 최근에 물었던 다른 question에 내 초기 아이디어보다 더 나은 해결책을 발견했습니다.

parapura rajkumar는 TypeConverter 클래스로 올바른 경로에 있었지만 예외가 아닌 이벤트에 대해서는 CanConvertFrom 메서드에 필요한 예외 처리가 피하려고했습니다.

메서드는 내 문제를 해결했지만 IsValid 메서드는 CanConvertFrom 메서드와 필수 예외 처리를위한 래퍼이므로 이상적이지 않습니다.

private Boolean CanCovert(String value, Type type) 
{ 
    TypeConverter converter = TypeDescriptor.GetConverter(type); 
    return converter.IsValid(value); 
} 
관련 문제