2012-12-09 42 views
6

Farklı genel türlere göre farklı sonuç almak için yöntem aşırı yüklemesini kullanmak istiyorum. İşe yaramıyor. Kodum açıkça gösteriyor.C# genel türü için aşırı yükleme hatası

static class Helper 
{ 

    public static bool Can(int i) 
    { 
     return true; 
    } 

    public static bool Can(Object o) 
    { 
     return false; 
    } 
} 

class My<T> 
{ 
    public static bool can = Helper.Can(default(T)); 
} 

Console.WriteLine(Helper.Can(default(int)));//True,it is OK 

Console.WriteLine(My<int>.can);//false?? why the overload doesn't work 
Console.WriteLine(My<Object>.can);//false 

Neden My<int> aramalar Helper.Can (Object o) ziyade Helper.Can (int i)?

cevap

4

Bu şekilde çalışmıyor.

Aşırı yükler tamamen derleme zamanında çözülür; Genel tip parametreleri çalışma zamanında çözülür.
Derleyici, T'un int olduğunu bilmediğinden, kodunuz her zaman Can(Object)'u arayacaktır.

+0

Great.Teşekkür ederiz – zilong

+0

"Genel tür parametrelerinin çalışma zamanında çözüldüğü" ifadesine tamamen katılıyorum. Öyleyse, derleyici derleme zamanında "" Listesinden bir int öğesi alamadığınızı söyleyemedi. Ne * *, derleme zamanında çözümlenmemiş olarak kabul edilenler, genel sınıf içindeki genel tür parametresinin oluşumlarıdır. –

+0

@ O.R.Mapper: Genel sınıfta demek istedim. – SLaks

1

bu biraz ayrıntılı, ancak Reflection kullanarak istediğini elde edebiliriz: Ek geminin biraz Tabii ki

My<string>.can == false 
My<int>.can == true 
My<object>.can == false 

,

class My<T> 
{ 
    static bool doStuff() 
    { 
     var rightMehod = typeof(Helper).GetMethods().Where(p => 
      { 
       if (!p.Name.Equals("Can")) 
        return false; 

       if (!p.ReturnType.Equals(typeof(bool))) 
        return false; 

       if (p.GetParameters().Length != 1) 
        return false; 

       var par = p.GetParameters().First(); 
       return par.ParameterType.Equals(typeof(T)); 
      }).FirstOrDefault(); 

     if (rightMehod == null) 
     { 
      return Helper.Can(default(T)); 
     } 
     else 
     { 
      return (bool)rightMehod.Invoke(null, new object[] { default(T) }); 
     } 
    } 

    public static bool can = doStuff(); 
} 

Bu şekilde (ve jenerik tiplerin kullanımı), bu snippet'i pek çok farklı durum için kapsamlı bir şekilde yeniden kullanabileceksiniz.

Bir ek not: Bu örnekte, belirli örnek için doğrudan tip karşılaştırması kullandım. Bu, miras alınan türlerle uğraşırken düzgün çalışmaz (ve tabii ki, bazı ek belirsizlikler de vardır :).

3

Genel olarak, derleme zamanında nesne için çözecektir ancak dinamik anahtar sözcüğünü kullanarak çalışma zamanı kadar beklemek için bunu söyleyebilirim: Eğer çalıştığınız şeyi

class My<T> 
{ 
    public static bool can = CanWithDynamic(); 

    private static bool CanWithDynamic() { 
     dynamic runtimeT = default(T); 
     return Helper.Can(runtimeT); 
} 

Yani, bunun için çalışacak Yapmak ve doğru aşırı yük denir. Ancak, çalışma zamanında çözülen herhangi bir şeyde olduğu gibi, onunla ilişkili bir performans maliyeti vardır. Muhtemelen bir değil, ama bu yöntemi sık sık çağırırsanız, bir etkisi olabilir.