Jakie wady ma C# i .NET?

3

@scibi92: "wersja sql" linq to syntax sugar, który pod spodem i tak jest tłumaczony do wersji z wywołaniami metod (method syntax). I owszem, chyba mało kto lubi pierwsza wersję. Chociaż muszę przyznać że musiałem ostatnio napisać zaawansowaną projekcję widoku, i o wiele łatwiej było mi użyć właśnie linq ponieważ mogłem użyć kilka poleceń let, co już z wywoływaniem metod nie jest takie ładne.

Co do Twojego komentarza na temat nazw metod z dużych liter to jest to oczywiście kwestia preferencji. Z własnego doświadczenia powiem jednak że bardziej niż o preferencje chodzi o przyzwyczajenia. Kiedyś zaczynałem od Javy i podanie metod z dużych liter po przejściu na C# wydawało mi się dziwne, następnie po dłuższym okresie pisania backendu przyszedł czas na full-stack i pisanie w JS. Wtedy znów okazało się że zmiana z jednego stylu na inny (duże litery na małe) wydawała mi się dziwna i brzydka. Natomiast dziś po kilku latach pisania full-stack zarówno jeden jak i drugi styl wydają mi się normalne, chociaż osobiście preferuję duże litery ponieważ wyraźnie rozróżniają zmienne od metod.

0

Ogólnie po chwili refleksji dochodzę do wniosku, że C# ma kilka absurdów.

  • List.forEach nie ma obsługi break; (nie wiem, dlaczego), ani dostępu do indeksu
  • Ogólnie pętla foreach na listach nie ma dostępu do indexu.
    Jakby się zastanowić, to można znaleźć więcej takich nieprzyjemnych elementów. Wszystkie można obejść.
4

Ogólnie, to nie ma czegoś takiego jak pętla foreach. To tylko lukier składniowy na wzorzec iteratora.

Co do meritum - to by było bardzo nielogiczne, gdyby foreach miał dostęp do indeksu, bo nie każda kolekcja wspiera coś takiego jak indeks.Jak zatem foreach z indeksem miałby się zachowywać dla takiej kolekcji?

0
somekind napisał(a):

@scibi92:

List<String> myList =
    Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList
    .stream()
    .filter(s -> s.startsWith("c"))
    .map(String::toUpperCase)
    .sorted();

Wersja w C# z LINQ:

var myList = new List<string> { "a1", "a2", "b1", "c2", "c1" };

var toPrint = myList
        .Where(x => x.StartsWith("c"))
        .Select(x => x.ToUpper())
        .OrderBy(x => x);

Jak dla mnie, to różnica jest w nazwach metod i konwencji, no i w tym, że w C# to po prostu działa na dowolnej kolekcji, bez wołania żadnego stream().

Jako ciekawostka

val toPrint = myList
        .filter { it.startsWith("c") }
        .map { it.toUpperCase() }
        .orderBy { it }

A w kodzie javovym jest bug bo jeszcze ten strumien trzeba z'collect'owac do listy :|

1

@renderme: lol, a Ty słyszałeś o czymś takim jak polimorfizm? Nie wiem jak to jest w C#, ale w Javie jest po prostu interface Iterable który ma tego forEacha. Skąd wiadomo że implementacja tego interfejsu będzie miała sekwencyjny charakter? Ew. mozna by dodac osobna metodę (przeładować nazwe) i zrobić forEach(BiConsumer<E e, Integer index> consumer) ale to i tak średnio pasuje do tego tylu for eacha

0

Z nienawiści około 8 lat temu przeszedłem do miłości do tego języka i platformy. To już dużo mówi ;)
A co do wad - pewnie coś powtórzę:

  • język wysokiego poziomu - to jednocześnie wada i zaleta. Konkretnie chodzi mi tutaj o konieczność obecności wirtualnej maszyny jako dodatkowej warstwy. Z drugiej jednak strony to też może być zaleta, a wydajnościowo nie jest chyba aż tak źle w porównaniu do języków natywnych
  • brak możliwości trzymania referencji jako pola w klasie. Chociaż nie jestem pewien, czy tu się coś nie zmieniło. I oczywiście można trzymać wskaźnik, ale z tym już w C# jest trochę zabawy
  • częste problemy z Visualem (chociaż to nie jest bezpośrednia wada języka)
5

@renderme: no i załóżmy, że będzie istniał taki foreach z indeksem. Napiszesz kod z użyciem takiej konstrukcji (bazujący na List), a potem ktoś zmieni typ kolekcji po prostu na IEnumerable, w którym indeksu nie ma. I co wtedy? Ma zostać użyta jakaś domyślna wartość indeksu, czy po prostu kod ma się przestać kompilować?
Oba rozwiązania są złe, bo zwiększają trudność utrzymania kodu.

A jeśli wiesz, że zawsze gdzieś będziesz miał List, i koniecznie potrzebujesz indeksów, to już jest do tego instrukcja. Nazywa się for.

0

@Juhas:

brak możliwości trzymania referencji jako pola w klasie. Chociaż nie jestem pewien, czy tu się coś nie zmieniło. I oczywiście można trzymać wskaźnik, ale z tym już w C# jest trochę zabawy

Chyba nie masz na myśli referencji do obiektu? Jeśli tak to jak najbardziej można, a wręcz nagminnie się to robi.

0
Juhas napisał(a):
  • brak możliwości trzymania referencji jako pola w klasie. Chociaż nie jestem pewien, czy tu się coś nie zmieniło. I oczywiście można trzymać wskaźnik, ale z tym już w C# jest trochę zabawy

Tu chyba masz na myśli referencje do typów prostych? No nie ma i bardzo dobrze. Oznaczałoby to możliwą zewnętrzną i niejawną zmianę stanu obiektu. Debugowanie błędów byłoby koszmarem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1