2013-03-12 16 views
5

Ayrı görünen farklı kısıtlamalara sahip aşırı yükleme yöntemleri ile ilgili bir sorunla karşılaştım. Bu benim örnektir:Farklı tür kısıtlamaları ile zaten tanımlanmış aynı imzaya sahip üye

public class A 
{ 
    public void Do<T>() where T : class 
    { 

    } 

    public void Do<T>() where T : struct 
    { 

    } 
} 

Ve bu aşağıdaki hata "zaten tanımlanmış aynı imzayla Üyesi" ile derleme yapmaz. Her iki koşulu bir kerede tatmin etmek mümkün mü yoksa sadece C# derleyicisinin sınırlaması mı?

cevap

8

O derleyici bir sınırlama değildir - bu dilin bir sınırlama var (ve büyük olasılıkla CLR yanı; emin değilim). Temel olarak, aşırı yüklenmelerle çatışanlardır - bu, dönüş türüne aşırı yüklenmeye çalışmak gibidir. Desteklenmiyor. Bu

bu aramalar tüm farklı yöntemlerin çağrımı için derlemek o tür yöntemleri beyan etmek mümkündür:

a.Do<int>(); 
a.Do<string>(); 
a.Do<int?>(); 

... ama her zaman isteğe bağlı parametreleri ve/veya parametre dizileri içerir ve bu horrible bu.

Ayrıca jenerik kısıtlamaları tarafından yüklenmeyin rağmen unutmayın, siz genel "Arity" (tip parametrelerinin sayısı) tarafından aşırı edebilirsiniz:

public void Foo() {} 
public void Foo<T>() {} 
public void Foo<T1, T2>() {} 
+0

En azından ben iki kısıtlamaları münhasır olduğunu söylemek doğru idi ve sadece sınırlama olmamasına dua , sağ? :) –

+0

@IlyaChernomordik: Bu bir sınırlama, ancak oldukça makul bir IMO. –

+0

Ama buna izin vermenin nesi yanlış? Sadece bir sınıf olup olmadığına bağlı olarak farklı eylemler yapmam gerekiyor (boş olup olmadığını kontrol edebilirim) ya da sadece uzun olduğu zaman (o değerin orada olduğunu biliyorum). Böylece çıkış yolu sadece göründüğü yöntemlere farklı isimler vermelidir. Ben kesinlikle korkunç bir şekilde kullanmak istemiyorum :) –

2

Sen varing bir aşırı yükleme yapamazsınız Genel parametre containts. Geçerli bir metot aşırı yüklemesi için, yönteme farklı giriş parametrelerine sahip olmanız gerekir. derlenmiş zaman

1

Her iki yöntem aşağıdaki ada sahip olmalıdır: jenerik parametrelerin sayısı itibariyle

A.Do``1 

yöntemin ya da sınıfın adı girer.

emin değil ne durumdur ancak bu yöntemleri çağırmak için yansıma faydalanmak gerekebilir:

public class A 
{ 
    public void Do<T>() 
    { 
     if(typeof(T).IsValueType){ 
      // nasty reflection to call DoValueType 
     } 
     else { 
      // nasty reflection to call DoReferenceType 
     } 
    } 
    private void DoReferenceType<T>() where T : class { 

    } 
    private void DoValueType<T>() where T : struct { 

    } 
} 
İlgili konular