2012-08-23 11 views
5

Bir jenerik sorunu çalıştırıyorum. bu yüzden aslında bir DI Resolver olarak SimpleInjector kullanıyorum ve üzerinde sınıf kısıtlaması vardırT'yi "T: class" kısıtlamasıyla eşleştirmek için bir sınıfa nasıl yazabilirsiniz? genel Bağımlılık Enjeksiyon işleyicisi (bir taban Servis Bulucu) üzerinde çalışırken

Okay (netlik için)

Düzenleme 1, işte GetInstance yöntemidir biraz daha komple bir koddur:

public T GetInstance<T>() where T : class 
    { 
    try 
    { 
     // works 
     return _container.GetInstance<T>(); 
    } 
    catch(ActivationException aEx) 
    { 
     return default(T); 
    } 
    } 

    public T GetInstance<T>() 
    { 
    try 
    { 
     if(typeof(T).IsClass) 
     { 
      // does not work, T is not a reference type 
      return _container.GetInstance<T>(); 
     } 
    } 
    catch(ActivationException aEx) 
    { 
     return default(T); 
    } 
    } 

Düzenleme 2 - bu yorumlarda tuhaf görünüyor beri nihai kodu:

public T GetInstance<T>() 
    { 
    try 
    { 
     if(typeof(T).IsClass) 
     { 
      return (T) _container.GetInstance(typeof(T)); 
     } 
    } 
    catch(ActivationException aEx) 
    { 
     return default(T); 
    } 
    } 
+5

biz dönen boş örnek dışında, bunu yapmaya ilgilenen nedeni hakkında daha fazla biliyordu Belki eğer ...? Yapılandırmak için daha iyi bir yol olabilir. –

+0

Lütfen neden bunu yapmak istediğimi 1'e bakın. – Laurence

cevap

1

Bir kere daha yardımcı yöntemini kullanabilir? Daha sonra uygun olanı çağırmak, GetInstance bir varyantını bulmak için yansıma kullanabilirsiniz

public class Test 
{ 
    public T GetInstance<T>() where T : class 
    { 
    return (T)GetInstance(typeof(T)); 
    } 

    private object GetInstance(Type type) 
    { 
    return Activator.CreateInstance(type); 
    } 

    public T GetEvenMoreGenericInstance<T>() 
    { 
    if(!typeof(T).IsValueType) 
    { 
     return (T)GetInstance(typeof(T)); 
    } 
    return default(T); 
    } 
} 
+0

Bu gerçekten çalışıyor, teşekkürler. I T döküm unuttu: 'halka T GetInstance () { { deneyin (typeof (T) .IsClass) { geri (T) _container.GetInstance (Typeof (T)); } } mandalı (ActivationException AEX) { dönüş varsayılan (T); } } ' – Laurence

1

Kısa cevap, en azından doğrudan değil, bunu yapamazsınız. derleyici bir sürü iş yapmak zorunda kalacak kesinlikle T daima durumda bir sınıf olacağını garanti, bu nedenle GetEvenMoreGenericInstance aynı tip kısıtlamasını uygulamadan bir genel tür parametre olarak iletin izin vermez.

Sen yansıma yoluyla bunu gerçekleştirmek ya da bir parametre olarak bir Tür alır GetInstance olmayan bir jenerik aşırı oluşturabilir. Bu yöntemi çağırmak ihtiyacını ortadan kaldırmak için Type parametre seçeneğini öneririm veya kodunuzu tamamen yeniden yapılandırabilirim.

0

altında test sınıf bulabilirsiniz.

Aşağıdaki örnek statik yöntemlere çağrı yapar, ama bunu uzatmak olabilir:

namespace Scratch 
{ 
    internal class Foo 
    { 
     // A class to create 
    } 

    class Program 
    { 
     public static T GetInstance<T>() where T : class, new() 
     { 
      return new T(); // Or whatever... 
     } 

     public static T CallGeneric<T>(Func<object> f) 
     { 
      var method = f.Method; 

      var converted = method.GetGenericMethodDefinition().MakeGenericMethod(typeof(T)); 

      return (T) converted.Invoke(null, new object[] {}); 
     } 

     public static T GetEvenMoreGenericInstance<T>() 
     { 
      if(!typeof(T).IsValueType) 
      { 
       return CallGeneric<T>(GetInstance<object>); 
      } 
      return default(T); 
     } 

     static void Main(string[] args) 
     { 
      var a = GetEvenMoreGenericInstance<int>(); 
      var b = GetEvenMoreGenericInstance<Foo>(); 
     } 
    } 
} 
+0

bir yansıma kullanımı gibi :) – Laurence

İlgili konular