2010-05-12 6 views
9

메소드에 매개 변수가 복잡한 유형 인 경우 도구를 작성하고 있는데 인스턴스화와 같은 특정 유형의 조치가 필요합니다.리플렉션을 사용하여 프리미티브 유형의 복합 유형 결정

Type 변수에서 IsPrimitive 속성을 확인했습니다. 그러나 복잡한 형식으로 stringdecimal이 표시되며 기술적으로 올바르지 않습니다. 그러나 정말로 원하는 것은 개발자가 생성 한 클래스 유형과 시스템 정의 데이터 유형을 구별 할 수 있어야한다는 것입니다.

내가 할 수있는 방법이 있습니까?

답변

8

decimal는 "복합 형"입니다; C#은 키워드를 가질 수 있지만 CLI 프리미티브가 아닙니다. String은 어느 쪽의 방식 으로든 논쟁 할 수 있습니다. 실제로는 그 자체가 하나의 유형입니다 (불확실한 크기 등 - 원격으로 비교할 수있는 유일한 것은 배열입니다).

그러나; 여기에 원하는 것을 결정할 방법이 없습니다. 가장 좋은으로 알려진 시스템 조립 (또는 아마도 서명 키)을 확인하는 것입니다. 결국, i를 System.Foo.Bar 네임 스페이스의 유형 System.something.dll 또는 Microsoft.something.dll라는 어셈블리를, (이것은 물론, 당신이 원하는 방법 편집증에 따라 다름) 쓸 수.

특성 또는 인터페이스를 통해 특수한 방식으로 처리하려는 자체 유형을 명시 적으로 표시하도록 devs를 얻는 것이 더 쉬울 수 있습니다.

+0

C#에서는 문자열이 분명히 복잡한 유형입니다. 그것들은 stuct 대신 클래스로 정의되어 차이점 만 표시하지만 문자열의 동작은 개념적으로 기본이 아닙니다. C#의 사용법은 기본 유형과 비슷하지만, 대부분 영리한 연산자 오버로딩과 몇 가지 특수 언어 기능 (예 : 문자열 리터럴의 C# 처리)을 통해 수행됩니다. –

+0

@Stephen - 동의하지 않습니다. struct vs class는 여기서 중요하지 않습니다. 타입과 마찬가지로 커스텀 구조체를 작성할 수 있습니다. 그리고 string의 "special"은 연산자와 같은 언어적인 것들을 훨씬 뛰어 넘습니다. –

+0

"complex"에 대한 정의에 따라 의미가있을 수도 있고 C#에서는 공식적으로 "complex type"이라는 용어를 사용하지 않는다고 생각합니다. 그것은 "custom"과 "value type"과 같은 용어를 가지고 있으며, sting도 마찬가지입니다. 문자열의 데이터가 문자열이 아닌 항목의 배열로 저장되므로 개념적으로 복잡하다고 생각합니다 ... 따라서 문자열의 데이터 사용은 기본 값 유형의 간단한 가져 오기보다 복잡한 동작에 따라 달라집니다. 기억. 하지만 복잡한 정의는 다를 수 있습니다. –

0

내장 유형을 사용하는 것이 사용자 생성 유형과 다른 점은 확실하지 않습니다. 더 큰 문제는 매개 변수없는 생성자가없는 유형의 인스턴스를 만드는 것입니다.

무엇을 하든지 객체 배열에 캐스팅해야만 MethodInfo.Invoke에 전달할 수 있으므로 어느 시점에 Activator.CreateInstance을 수행해야합니다.

사용자가 필드에 항목을 입력 한 다음 단추를 눌러 메서드를 호출 할 수있는 경우 리플렉션을 사용하여 형식의 TryParse/Parse 정적 메서드를 찾고 해당 메서드를 호출하는 것이 가장 좋습니다 입력을 검증/구문 분석하기 위해. 여기

문자열로 변환 할 수 있습니다 대부분의 시스템 유형에 대해 암시 적으로 작동하는 코드 조각입니다 : 확실히

var parseMethod = typeof(int).GetMethods().FirstOrDefault(
    m => m.IsStatic && 
     m.Name == "TryParse" && 
     m.GetParameters().Length == 2 && 
     m.GetParameters()[0].ParameterType == typeof(string) && 
     m.GetParameters()[1].IsOut); 
if(parseMethod != null) { 
    bool result = (bool)parseMethod.Invoke(null, new object[]{"45", null}); 
    //result == true 
    result = (bool)parseMethod.Invoke(null, new object[] { "blah", null }); 
    //result = false 
} 
+0

실제 매개 변수없는 생성자 (개인 집합이 아닌)가없는 유형의 인스턴스를 만드는 것은 그리 큰 일이 아니지만 *주의해야합니다. 대부분의 코드에는 권장되지 않습니다. 직렬화 API와 같은 경우에만 적합합니다. –

+0

오, 나는 당신이 그렇게 할 수 있는지 몰랐다. –

2

좀 더 세련된 방법이 있는지 확실하지 않지만 네임 스페이스 시스템 또는 시스템 어셈블리에 대해 유형의 네임 스페이스 또는 AssemblyQualifiedName을 확인하면 잘 될 것이라고 생각합니다.

4

내가 검색을 수행하는 동안이 스레드에서 발견되었습니다. 나는 이것에 대한 해결책을 찾고 있었고 네임 스페이스를 검사하여 네임 스페이스에 속성이 정의되어 있는지 확인했다.

if (property.PropertyType.Namespace.StartsWith("MyApp.MyNamespace")) 
{ 
     // logic for properties in MyNamespace 
} 

희망이 있으면 도움이 될 것입니다.

관련 문제