2014-11-26 10 views
5

Bir özel durumdan kaçınmak istediğimden, bir türün parametresiz bir kurucu olup olmadığını kontrol etmek istiyorum. Bunu nasıl başarabilirim?Parametre oluşturucu için bir tür nasıl kontrol edilir?

Böyle bir şey gerekir:

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

DÜZENLEME: Ben kaynakla aynı türde bir nesne oluşturmak istediğiniz ve değil onun yerine varsayılan (TT) kullanmak istediğiniz bir varsayılan kurucu varsa.

 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; 
    } 

Ama çek bana gerçek verir ve Createınstance istisna

yok parametresiz oluşturucu

Çözüm atar:

Ya şimdi var olan

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

Bu şekilde birçok özyinelemeli işlev ve yineleme söz konusuydu ve bu şekilde bir yere HasDefaultConstructor (tip nesnesiyle) yanlış genel işlevi çağrıldı. Jenerik olmayan bir işlev kullanmak hile yaptı.

Yapıcı yardımlarınız için hepinize teşekkür ederiz.

+0

Sorunuzu netleştirmek edin - nasıl inşa edici çağırmak istersin? Parametre olmayan bir kurucu yoksa bir istisna beklediğiniz için, 'TT' için belirtilen türün böyle bir kurucuya sahip olmasa bile kodun yine de derlenebilir olmasını istiyorsunuz. –

+0

Varsayılan kurucu yoksa, onun yerine varsayılan (TT) kullanmak istiyorum. – MTR

+0

Aha! Öyleyse lütfen sorunuzdaki bilgileri ekleyin.Sorunun anlamını önemli ölçüde değiştirir ve 'new()' jenerik kısıtlaması geçersiz olan herhangi bir cevap verir. –

cevap

9

GetConstructor(Type.EmptyTypes) parametresiz yapıcı dönmek veya boş bir yoksa, bu nedenle olabilir olacak:

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

DÜZENLEME Sorununu tahmin ediyorum

TT olmasıdır ve source.GetType() aslında iki farklı tiptir. source.GetType(), büyük olasılıkla TT'dan gelir, ancak parametresiz bir kurucu yoktur. Yani aslında yapmanız gereken source.GetType() için çek yapmak geçerli:

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

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

Haklısın. Bazı özyinelemeli fonksiyonlar yoluyla yolda bir yerde tür hakkında bilgi kayboldu. Böylece, nesne için (gerçek tip için değil) genel işlevler çağrıldı ve gerçekten de GetType ve TT aynı değildi. Source.GetType() kullanılarak yardım edildi. – MTR

8

Türün parametresiz bir kurucu olup olmadığını kontrol etmek için yansıma kullanın. Type.GetConstructor kullanın: Sadece TT bir örneğini oluşturmak istiyorsanız, new sınırlamayı kullanır

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 önerildiği gibi

, ayrıca kurucular bulmak için bu kodu kullanabilirsiniz o public değil. Benim düşünceme göre, bunu sadece son çare olarak kullanmalısınız!

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

Elbette, aynı zamanda genel olmayan bir sıfır parametresi yapıcıyı da kabul ederseniz, 'typeof (TT) .GetConstructor (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, new [] {}, Null) yazın. –

+1

@JeppeStigNielsen: İsteğinize göre öneri olarak önerinizi eklediniz. –

+0

HasDefaultConstructor sürümünüz bana doğruyu veriyor, ancak aşağıdaki CreateInstance istisnayı atar. – MTR

İlgili konular