2014-11-26 10 views
5

예외를 피하기 위해 유형에 매개 변수없는 생성자가 있는지 확인하고 싶습니다. 이것을 어떻게 할 수 있습니까?매개 변수없는 생성자의 형식을 확인하는 방법은 무엇입니까?

는이 같은 뭔가가 필요 :

bool HasDefaultConstructor<TT>(TT source) 
{ 
    return ???; 
} 

편집 : 나는 소스로 같은 유형의 객체를 생성 할 그렇지 않은 내가 대신 기본 (TT)를 사용하고자하는 기본 생성자가있는 경우.

 static TT CreateObject<TT>(TT source) 
    { 
     try 
     { 
      if(!HasDefaultConstructor<TT>(source)) 
      { 
       return default(TT); 
      } 
      return (TT)Activator.CreateInstance(source.GetType()); 
     } 
     catch(Exception ex) 
     { 
      Trace.WriteLine("Exception catched!\r\n" + ex); 
     } 
     return default(TT); 
    } 
    static bool HasDefaultConstructor<TT>(TT source) 
    { 
     ConstructorInfo c = typeof(TT).GetConstructor(new Type[] { }); 

     return c != null; 
    } 

그러나 검사는 나에게 진정한 제공하고 때 CreateInstance 예외를

없음 매개 변수가없는 생성자

솔루션 던졌습니다 :

내가 지금있는 것은

bool HasDefaultConstructor(Type t) 
{ 
    return t.GetConstructor(Type.EmptyTypes) != null; 
} 

많은 재귀 함수와 반복이 있었고 이런 방식으로 어딘가에 있지만 잘못된 일반 함수 인 HasDefaultConstructor (객체 유형 사용)가 호출되었습니다. 비 제네릭 함수를 사용하는 것이 트릭을 만들었습니다.

건설적인 도움을 주셔서 감사합니다.

+0

질문을 명확히하십시오 - 당신은 어떻게 생성자를 호출 할 수 있습니까? 매개 변수없는 생성자가 없다면 예외가 발생할 것으로 예상되므로, 'TT'에 표시된 유형에 해당 생성자가 없더라도 여전히 컴파일 가능한 코드를 원하십니까? –

+0

기본 생성자가없는 경우 기본값 (TT)을 대신 사용하려고합니다. – MTR

+0

아하! 그런 다음 해당 정보를 질문에 포함하십시오.그것은 질문의 의미를 현저히 바꾸고'new()'제네릭 제약 조건을 참조하는 응답을 무효로 만듭니다. –

답변

9

GetConstructor(Type.EmptyTypes)는 매개 변수가없는 생성자를 반환, 또는 null 존재하지 않는 경우, 그래서 당신은 할 수있는 것 :

return typeof(TT).GetConstructor(Type.EmptyTypes) != null; 

편집 나는 문제를 추측하고있어

TT을 것입니다 source.GetType()은 실제로 두 가지 유형입니다. source.GetType()은 아마도 TT에서 파생되었지만 매개 변수없는 생성자가 없습니다. 그래서 당신이 실제로 무엇을해야하는지는 source.GetType()에 대한 검사를 할 수 있습니다 :

bool HasDefaultConstructor(Type t) 
{ 
    return t.GetConstructor(Type.EmptyTypes) != null; 
} 

if(!HasDefaultConstructor(source.GetType())) 
    ... 
+0

맞습니다. 일부 재귀 함수를 거치는 중에 어딘가에 유형에 대한 정보가 없어졌습니다. 따라서 객체의 일반 함수 (실제 유형이 아닌)가 호출되었으며 실제로 GetType과 TT는 동일하지 않았습니다. source.GetType()을 사용하면 도움이됩니다. – MTR

8

리플렉션을 사용하여 유형에 매개 변수없는 생성자가 있는지 확인하십시오. Type.GetConstructor 사용 : 그냥 TT의 인스턴스를 생성 할 경우, new 제약 사용

bool HasDefaultConstructor<TT>() 
{ 
    ConstructorInfo c = typeof(TT).GetConstructor(new Type[] { }); 
    // A constructor without any types defined: no parameters 

    return c != null; 
} 

:

TT CreateUsingDefaultConstructor<TT>() where TT : new() 
{ 
    return new TT(); 
} 
Jeppe Stig Nielsen 제안으로

, 당신은 또한 생성자를 찾으려면이 코드를 사용할 수를 그 public이 아닙니다. 제 의견으로는, 이것을 최후의 수단으로 만 사용해야합니다!

typeof(TT).GetConstructor(BindingFlags.Instance 
          | BindingFlags.NonPublic 
          | BindingFlags.Public 
         , null 
         , new Type[] { } 
         , null 
         ) 
+3

물론 public이 아닌 매개 변수없는 생성자도 허용한다면 typeof (TT) .GetConstructor (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new 유형 [] {}, null)'. –

+1

@JeppeStigNielsen : 귀하의 제안을 속성에 추가했습니다. –

+0

귀하의 HasDefaultConstructor 버전이 사실이지만, 다음 CreateInstance 예외가 발생합니다. – MTR

관련 문제