Czytałem wywiad z Joshua Blochem w Coders at Work, gdzie ubolewał nad wprowadzeniem generycznych w Javie 5. Nie podoba mu się konkretna implementacja w dużej mierze dlatego, że obsługa wariancji - jałowe karty Java - sprawia, że jest ona niepotrzebnie skomplikowana.C# generics - bez dolnych granic według projektu?
Z tego co wiem, C# 3 nie ma nic takiego jak wyraźne, ograniczone symbole wieloznaczne, np. nie można zadeklarować metody PriceBatch, która pobiera kolekcję zasobów lub dowolnej podklasy Asset (void PriceBatch(Collection<? extends Asset> assets)
w Javie?).
Czy ktoś wie dlaczego symbole wieloznaczne i ograniczenia nie zostały dodane do C#? Czy te funkcje zostały celowo pominięte, aby uczynić język prostszym, czy jest to coś, czego po prostu nie udało się jeszcze wdrożyć?
EDYCJA: Święty dym, komentarze samego Erica Lipperta! Po przeczytaniu jego i wnikliwe komentarze Pawła, zdaję sobie sprawę, że przynajmniej górne granice są obsługiwane i że powyższy przykład można przetłumaczyć do C# jak:
void PriceBatch<T>(ICollection<T> assets) where T : Asset
dolnych granic, z drugiej strony, są najwyraźniej nie jest obsługiwany jako Eric mówi w swoim drugim komentarzu, np prawdopodobnie nie ma możliwości bezpośredniego przetłumaczenia tego (nieco spreparowanego) kodu Java na C#:
public class Asset {}
public class Derivative extends Asset {}
public class VanillaOption extends Derivative {}
public static <T extends Asset> void copyAssets(Collection<T> src, Collection<? super T> dst) {
for(T asset : src) dst.add(asset);
}
Collection<VanillaOption> src = new ArrayList<VanillaOption>();
[...]
Collection<Derivative> dst = new ArrayList<Derivative>();
[...]
copyAssets(src, dst);
Czy mam rację? Jeśli tak, to czy istnieje szczególny powód, dla którego C# ma górne, ale nie niższe granice?
Nie rozumiem pytania; C# ma ograniczone generyczne i od C# 2. Czy to, co uzyskujesz w tym języku, obsługuje * kowariancję i kontrawariancję * call-site * na skonstruowanych rodzajach ogólnych? Ponieważ C# nie obsługuje tego; C# 4 będzie obsługiwać * wariancję deklaracji-witryny *. –
Czy to, co robisz, polega na tym, że granice parametrów typu na ogólnych metodach są potrzebne tylko od granic, a nie od granic? C# nie obsługuje tego drugiego; Java i Scala wierzę. –
Dzięki, zaktualizowałem pytanie. – ehnmark