Neden yok C# "türlerini birleştirmek" olabilir; farklı temel sınıflardan elde ne zaman?derleyici şikayet
Non-derleme benim geçerli kod şuna benzer:
public abstract class A { }
public class B { }
public class C : A { }
public interface IFoo<T>
{
void Handle(T item);
}
public class MyFoo<TA> : IFoo<TA>, IFoo<B>
where TA : A
{
public void Handle(TA a) { }
public void Handle(B b) { }
}
C# derleyicisi bu derlemeye, aşağıdaki kural/hata gerekçe göstererek reddetti:
'MyProject.MyFoo<TA>' uygulamak 'MyProject.İFoo<TA>' ve 'MyProject.İFoo<MyProject.B>' çünkü onlar tipinde parametre oyuncu değişikliği birleştirmek olabilir
Bu hata ne anlama geldiğini anlıyorum; eğer TA
herhangi bir şey olabilir eğer teknik olarak da Handle
iki farklı uygulamalar konusunda belirsizlik tanıtmak hangi B
olabilir.
Ama TAolamazherhangi bir şey olabilir. Türü hiyerarşisi, TA
dayanarakolamazB
- en azından, bilmiyorumdüşünüyorumolabilir. TA
yok A
, türetilmesi gerekirdeğilbirden fazla C sınıfı miras yok açıkçası B
ve türevi#/.NET.
Ben genel parametre kaldırın ve C
hatta A
TA
değiştir, derler.
Neden bu hatayı alıyorum? Ya da genel istihbarat BM derleyici, yoksa kaçırdığım başka bir şey mi bir hata var?
Herhangi bir geçici çözüm veya sadece TA
türetilmiş her tür için genel olmayan ayrı bir sınıf olarak yeniden hayata MyFoo
genel sınıf olacak mıyım?
CEVAP
Bu 13.4.2 C Birleşik Devletleri:# 4 belirtimi, bölüm bir sonucudur
Eğer herhangi bir olası inşa edilen C tipi oluşturulan bir tür bağımsız değişkenleri L terk ettikten sonra, ben iki arabirim aynı olması neden olursa, o zaman C ilanının geçersiz. Kısıtlama tanımlamalar Olası inşa edilen her türlü belirlenmesinde dikkate alınmaz.
İkinci cümle yok edin.
Bu nedenle derleyici bir hata değil; derleyici doğru. Bir dil belirtimi bir kusur olduğunu iddia edebilir.
Genel olarak konuşursak, kısıtlamaları olan bir gerçek genel bir tür hakkında bir çıkarım olmalı her durumda göz ardı edilir. Kısıtlamaları çoğunlukla belirlemek için kullanılıretkili temel sınıfgenel tür parametre, ve biraz başka.
Ne yazık ki, bazen dilini keşfettim gibi gereksiz yere sıkı olduğu bir duruma yol açar.
Genel olarak "arayüzü iki kez, bir şekilde genel tür bağımsız değişkenleri yalnızca ayırt." aynı uygulamaya kötü kod kokusunu Örneğin, kaplumbağalar bir dizi de, o C nedir class C : IEnumerable<Turtle>, IEnumerable<Giraffe>
-- olması tuhafvezürafalar bir diziaynı zamanda? Burada yapmaya çalıştığın gerçek şeyi tarif EDEBİLİR MİSİN? Gerçek sorunu çözmek için iyi bir model olabilir.
Aslında eğer arayüzü tam olarak tarif ettiğiniz gibi
interface IFoo<T>
{
void Handle(T t);
}
Sonra arayüz çoklu kalıtım bir sorun çıkarıyor. Doğal olarak bu arayüzü karşıtı yapmak için karar verebilirsiniz:
interface IFoo<in T>
{
void Handle(T t);
}
Şimdi varsayalım
interface IABC {}
interface IDEF {}
interface IABCDEF : IABC, IDEF {}
Ve
class Danger : IFoo<IABC>, IFoo<IDEF>
{
void IFoo<IABC>.Handle(IABC x) {}
void IFoo<IDEF>.Handle(IDEF x) {}
}
Ve şimdi her şey iyice çığırından...
IFoo<IABCDEF> crazy = new Danger();
crazy.Handle(null);
Kolu uygulama çağrılır???
Bu makale ve bu konuda daha fazla düşünce için bkz: açıklamalar:
Neden 1/1/1970 "zaman" Çağ;?...
Ne zaman " = x" farklı "...
Neden scanf () "%lf" printf ...
Neden't radyo düğmeleri "sal...
Neden Java "ulaşılamaz deyimi&quo...