Funkcje C # lub .Net do odcięcia przy założeniu, że nie jest wymagana kompatybilność wsteczna? [Zamknięte]


18

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ź.



4
Pytanie wyraźnie nie jest konstruktywne zgodnie z wytycznymi i wyraźnie konstruktywne w oparciu o fantastyczne odpowiedzi. Głosowanie w celu ponownego otwarcia.
psr

1
szkoda, że ​​się zamknęło, ale może Eric opublikuje to na blogu zamiast tutaj?
jk.

Odpowiedzi:


35

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.


1
Uzgodnione, anonimowe metody były świetne, gdy nie mieliśmy lambdów ... teraz są po prostu zbędne.
Michael Brown

9
Jest jedna szczególna cecha anonimowych metod, która jest znacznie lepsza niż wyrażenia lambda .... ich idealne imię !!
odkrywca

1
W tym momencie nawet nie pamiętam składni anonimowej metody w C #. Muszę to sprawdzić, jeśli z jakiegoś dziwnego powodu muszę użyć jednego zamiast lambda.
Kyralessa

33

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ć

var customObjects = container.CustomObjects.Cast<CustomObject>();

Za każdym razem, gdy muszę to robić, umiera niewielka część mojej duszy.


To jest za świetne.

1
Nie wszystkie porty .NET obsługują rodzajowe. .NET Micro jest przykładem. Może nie mieć zastosowania, jeśli obiekty CustomObjects nigdy nie zostaną przeniesione na tę platformę.
goodguys_activate

2
To zaleta, że ​​nie ma duszy.
CaffGeek

29

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 na IntPtr. (I void**z IntPtr*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>i Action<T>delegatów. Action<T>jest po prostu Func<T, Unit>.


4
... i Taskjest po prostu Task<Unit>. Ponowne wdrożenie fragmentów biblioteki asynchronicznego CTP sprawiło, że naprawdę tego chciałem ...
Jon Skeet

24

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 {}.


7
Nie wspominając już o ogromnym spadku wydajności wynikającym z 64-bitowego JIT </snark>.
Jesse C. Slicer

7
Puste stwierdzenie ma negatywny wpływ na wydajność? Dlaczego?
quentin-starin

22

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).


Absolutnie zamierzałem to zapisać, kiedy zobaczyłem tytuł pytania - pobiłeś mnie do niego :(
Chris Smith

1
Przydatna jest możliwość otrzymania odniesienia do tablicy kowariantnej i bezpiecznego zapisu do odczytanych z niej odniesień do tablicy . Jeśli podobnie jak IList<T>dziedziczony IReadableList<out T>i nieprzewidziany IPemutable, może obsługiwać takie rzeczy jak sortowanie, ale tablice obsługują go łatwiej.
supercat

14

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 +xnie jest operatorem wstępnego zwiększania ++x, nie jest operatorem wstępnego zwiększania x++i nie jest operatorem dodawania binarnego x+y.)


1
dla (int i = 0; i <pułap; i ++)
Michael Brown

13
On nie mówi o preincrement i operatorów postincrement: on mówi o jednoargumentowego Plus, przeciwieństwo znakiem ujemnym na numer: +1 == 1. To dość cholernie blisko no-op.
Jesse C. Slicer

8
Nie chodzi tylko o wpływ na wyjściu czytelnej maszynowego, może poprawić wygląd kodu dla ludzi: if(a == +1 || a == -1){...}.
Thomas Bratt,

5
@ShuggyCoUK: Szczególnie dziwne jest to, że można go przeciążać . Ponieważ to się często zdarza. Wiesz, jak piszesz trochę JavaScript i myślisz, stary, chciałbym, żeby JS pozwolił mi tworzyć jednoargumentowe zdefiniowane przez użytkownika plus semantykę operatora, jak C # .
Eric Lippert,

2
@Eric Nie zdawałem sobie sprawy, że to jest przeciążalne. wow, możesz zrobić z tym okropne zaciemnienie :)
ShuggyCoUk

12

Domyślne literały liczbowe to double

W przypadku większości aplikacji biznesowychdecimal 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).


Być może skłaniam się do identyfikowania literałów, które sugerują wartość, której nie można przedstawić jako podwójne / zmiennoprzecinkowe dokładnie ...
ShuggyCoUk

Jeśli są w Javie - odnieś je do świętych tekstów Joshua Blocha „projekt lub dokument do dziedziczenia, albo zabraniają go” martinfowler.com/bliki/DesignedInheritance.html IIRC kotlin domyślnie uszczelnia klasy, więc przemysł przechodzi do lepszy kierunek w tym względzie.
Elazar Leibovich

Dlaczego klasy powinny być zapieczętowane?
James

@James: Dokładnie z powodów, które podaje Josh. Zaprojektowanie klasy, która umożliwia dziedziczenie w rozsądny, spójny sposób, zajmuje dużo czasu - a zrobienie tego bez wiedzy o tym, w jaki sposób zostanie zastosowane dziedziczenie, jest jeszcze gorsze.
Jon Skeet

1
@Pacerier: Pomyśl na przykład o niezmienności. Klasa niezapieczętowana nie może twierdzić, że jest niezmienna, ponieważ podklasy mogą wprowadzać zmienność.
Jon Skeet

7

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 .


6

Ja wiem, istnieją duże różnice między poszczególnymi klasami timera. Ale czy w ogóle nie moglibyśmy się ich pozbyć?


4

Metody i typów Arrayi List<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ć delegatem Func<T, T, int>

3
Podoba mi się, Predicate<T>ponieważ wychwytuje cel użycia tej funkcji i oszczędza trochę pisania.
Zebi

2

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.


3
Jak zdefiniowałbyś delegata do metody, która przyjmuje odwołanie za pomocą Action lub Func? Jak zdefiniowałbyś kombinator za pomocą Func? Oznacza to, że nie można powiedzieć „delegować DD (D d);” z Func.
Eric Lippert,

2
hmmm ... Poprawiłem się. Dlatego zostawiam zadanie tworzenia narzędzi, których używam w twoich zdolnych rękach;)
Michael Brown

@EricLippert: Chciałbym zobaczyć specjalną klasę delegatów, która poprzez magię CLR zawiera delegatów „każdego” arity i kombinacji parametrów wartości / referencji [wyszukiwanie delegata w klasie magii o odpowiednio sformatowanej nazwie stworzyłoby typ] i niech odziedziczą po nim wszyscy delegaci odpowiedniego podpisu. Kod, który chce konkretnego delegata, nadal wymaga dokładnego typu, ale kod, który chce konkretnego podpisu, mógłby użyć magicznej nazwy.
supercat

-1

Usługi sieciowe asmx

Myślę, że obecnie są dość przestarzałe w WCF.


6
Tak, ale czasem o wiele łatwiejsze w użyciu. . .
Wyatt Barnett

-2

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.


Winforms wydaje się znacznie bardziej stabilny, szybszy i mniej
błędny

Kiedy musisz tylko zhakować małą aplikację komputerową, WPF jest poważną przesadą.
Kyralessa

Wydaje się, że pomiędzy WPF stał się dość przestarzały na korzyść WinRT. Wydaje mi się jednak, że Winforms żyje bardziej niż WPF w rozwoju biznesu. Zobacz także stackoverflow.com/questions/913417/…
Doc Brown
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.