Ewoluuje każdy produkt lub struktura. Przede wszystkim ma to na celu zaspokojenie potrzeb użytkowników, wykorzystanie nowych mocy obliczeniowych i po prostu ulepszenie. Czasami główny cel projektu zmienia się również wraz z produktem. Framework C # lub .net nie jest wyjątkiem. Jak widzimy, obecna 4. wersja różni się znacznie od pierwszej. Ale rzecz stanowi barierę dla tej ewolucji - wstecznej kompatybilności.
W większości frameworków / produktów niektóre funkcje zostałyby odcięte, gdyby nie było potrzeby obsługi kompatybilności wstecznej. Według ciebie, jakie są te funkcje w C # /. Net?
Podaj jedną funkcję na odpowiedź.
c#
.net
features
backward-compatibility
Gulszan
źródło
źródło
Odpowiedzi:
Anonimowe metody . Myślę, że wszyscy zgadzają się, że anonimowa składnia metody wybrana dla C # 2.0 jest masywna i niezgrabna w porównaniu do składni lambda dodanej do C # 3.0. Bardzo niefortunnie jest mieć dwie prawie identyczne składnie, aby zrobić to samo.
źródło
Pozbyłbym się zbiorów innych niż ogólne. Są obrzydliwością ... i jest zbyt wiele przypadków, w których używam linq i muszę coś zrobić
Za każdym razem, gdy muszę to robić, umiera niewielka część mojej duszy.
źródło
nieważne jako typ . Dlaczego, u licha, „pustka” jest typem? Nie ma instancji, nie ma wartości, nie można go używać jako argumentu typu ogólnego, typu parametru formalnego, typu lokalnego, typu pola lub typu właściwości. Nie ma znaczenia jako typ; jest raczej faktem na temat wpływu wywołania metody na stos maszyny wirtualnej. Ale maszyna wirtualna to po prostu: maszyna wirtualna. Prawdziwa maszyna umieści zwracaną wartość w rejestrze (zazwyczaj EAX na x86) i nie wpłynie w ogóle na stos! Pustka jako typ to po prostu zły pomysł dookoła.
Gorzej: gdy jest używany jako typ wskaźnika, ponieważ w
void*
nim oznacza coś zupełnie innego niż to, co oznacza, gdy jest używany jako typ zwracany. Teraz oznacza „wskaźnik do miejsca przechowywania nieznanego typu”, co nie ma nic wspólnego z jego znaczeniem jako „metoda, która nie zwraca żadnej wartości”.Możemy wymienić
void*
jako typ wskaźnika naIntPtr
. (Ivoid**
zIntPtr*
i tak dalej.) Możemy zastąpić void jako typ zwracany przez „Unit”, typ, który ma jedną wartość, a mianowicie null. Implementacja CLR mogłaby następnie zdecydować, że wywołanie funkcji typowanej dla jednostki może odpowiednio zoptymalizować wykorzystanie rejestrów lub stosów, wiedząc, że zwracane wartości null można bezpiecznie zignorować.W takim świecie nie potrzebujesz już oddzielnych
Func<A, R>
iAction<T>
delegatów.Action<T>
jest po prostuFunc<T, Unit>
.źródło
Task
jest po prostuTask<Unit>
. Ponowne wdrożenie fragmentów biblioteki asynchronicznego CTP sprawiło, że naprawdę tego chciałem ...Puste oświadczenie
;
. Podatny na błędy, prawie zawsze literówka, i nie daje żadnego dodatkowego znaczenia, które nie zostało jeszcze wyrażone przez{}
.źródło
Niebezpieczna kowariancja dla tablic typu referencyjnego . Przy włączonej kowariancji typu
IEnumerable<T>
, przynajmniej część potrzeby kowariancji macierzowej zniknęła. (Gdybyśmy mieli kowariantny interfejs listy tylko do odczytu, to nie potrzebowalibyśmy go wcale).źródło
IList<T>
dziedziczonyIReadableList<out T>
i nieprzewidzianyIPemutable
, może obsługiwać takie rzeczy jak sortowanie, ale tablice obsługują go łatwiej.Jednoargumentowy operator plus . Najmniej użyteczny operator wszechczasów. Gdybyśmy nie musieli go trzymać dla kompatybilności wstecznej, wyjąłbym to w mgnieniu oka. Kto z tego korzysta, ktoś?
(Wyjaśnienie: Operator jednoargumentowy plus
+x
nie jest operatorem wstępnego zwiększania++x
, nie jest operatorem wstępnego zwiększaniax++
i nie jest operatorem dodawania binarnegox+y
.)źródło
+1 == 1
. To dość cholernie blisko no-op.if(a == +1 || a == -1){...}
.Domyślne literały liczbowe to
double
W przypadku większości aplikacji biznesowych
decimal
jest to bardziej odpowiednie ... a może lepiej byłoby po prostu usunąć ideę domyślnej i zmusić programistę do dokonania wyboru.(To „usuń domyślne” byłoby również odpowiednie dla niektórych innych rzeczy. Na przykład zrezygnowałem z prób przekonania wszystkich, że klasy powinny być domyślnie zapieczętowane, ale podejrzewam, że łatwiej jest przekonać ludzi, że powinni o tym pomyśleć czy ich nowa klasa powinna być zapieczętowana, czy też nie, i wyraź to).
źródło
Jest to raczej wskazówka niż funkcja, ale myślę, że jest ważna, ponieważ jest już zbyt głęboko zakorzeniona w ludzkich umysłach jako kanoniczne i najlepsze rozwiązanie:
Oficjalny wzór do wdrożenia
IDisposable
.Jest to uciążliwe i istnieją lepsze sposoby .
źródło
Ja wiem, istnieją duże różnice między poszczególnymi klasami timera. Ale czy w ogóle nie moglibyśmy się ich pozbyć?
źródło
Metody i typów
Array
iList<T>
które stały się przestarzałe wraz z Linq, na przykład:Array.TrueForAll
można zastąpićEnumerable.All
Array.FindAll
można zastąpićEnumerable.Where
List<T>.ConvertAll
można zastąpićEnumerable.Select
Predicate<T>
można zastąpićFunc<T, bool>
Converter<T,R>
można zastąpićFunc<T, R>
IComparer<T>
naprawdę powinien być delegatemFunc<T, T, int>
źródło
Predicate<T>
ponieważ wychwytuje cel użycia tej funkcji i oszczędza trochę pisania.Nieogólni delegaci Podobnie jak nieogólne kolekcje, nieogólni delegaci są bezużyteczni teraz, gdy mamy serię Func i Action. I odciąłbym warianty przy trzech parametrach. Jeśli masz więcej niż trzy parametry, utwórz strukturę i użyj tego jako pojedynczego parametru. Zadeklarowanie konkretnego delegata do obsługi zdarzeń nie jest zbyt OSADNE.
źródło
Usługi sieciowe asmx
Myślę, że obecnie są dość przestarzałe w WCF.
źródło
Winforms
Byłoby miło nie musieć nawigować między dwiema platformami stacjonarnymi. WPF to miejsce, w którym wszystko się dzieje, więc frustrujące jest posiadanie pełnej nadmiarowości na poziomie platformy.
źródło