C # або .Net функцій, щоб вимкнути, якщо припустити, що зворотна сумісність не потрібна? [зачинено]


18

Будь-який продукт або рамки розвиваються. В основному це робиться для задоволення потреб своїх користувачів, використання нових обчислювальних повноважень та просто покращення їх. Іноді основна мета дизайну також змінюється разом із продуктом. Структура C # або .net не є винятком. Як бачимо, сьогоднішня четверта версія сильно відрізняється порівняно з першою. Але річ постає як барикада на цю еволюційну сумісність.

У більшості рамок / продуктів є функції, які були б відрізані, якби не було необхідності підтримувати відсталу сумісність. Як ви думаєте, які ці особливості в мережі C # /.

Будь ласка, зазначте одну характеристику на відповідь.



4
Питання, очевидно, не конструктивне згідно з настановами, а чітко конструктивне на основі фантастичних відповідей. Голосування за повторне відкриття.
пс

1
ганьба це закрито, все ж, може, Ерік буде блогувати це замість відповіді тут?
jk.

Відповіді:


35

Анонімні методи . Я думаю, що всі згодні з тим, що синтаксис анонімного методу, обраний для C # 2.0, є приємним і незграбним порівняно з синтаксисом лямбда, який ми додали до C # 3.0. Дуже прикро мати два майже однакових синтаксису, щоб зробити те саме.


1
Домовились, анонімні методи були чудовими, коли у нас не було лямбдів ... тепер вони просто зайві.
Майкл Браун

9
Є одна особливість анонімних методів, що набагато краще, ніж лямбда-вирази .... їх ідеальне ім'я !!
explorest

1
На даний момент я навіть не пам'ятаю синтаксис анонімного методу в C #. Мені доведеться шукати це, якби з якихось химерних причин мені потрібно було використовувати його замість лямбда.
Kyralessa

33

Я б позбувся колекцій, що не є загальними. Вони гидота ... і є занадто багато випадків, коли я використовую linq і мені доводиться робити щось подібне

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

Щоразу, коли мені доводиться це робити, помирає невелика частина моєї душі.


Це занадто здорово.

1
Не всі порти .NET підтримують Generics. .NET Micro - приклад. Може не застосовуватися, якщо CustomObjects ніколи не перейде на цю платформу.
goodguys_activate

2
Це перевага в тому, щоб не мати душі.
CaffGeek

29

порожнеча як тип . Чому на землі "недійсний" тип? У нього немає примірників, у нього немає значень, ви не можете використовувати його як аргумент загального типу, формальний тип параметра, локальний тип, тип поля або тип властивості. Він не має значення як тип; швидше, це факт про те, який ефект має виклик методу на стек віртуальної машини. Але віртуальна машина - це саме це: віртуальна машина. Справжня машина поставить повернене значення в регістр (як правило, EAX на x86) і взагалі не вплине на стек! Пустота як тип - лише погана ідея навколо.

Гірше: коли використовується в типі вказівника, оскільки void*він щось означає зовсім інше, ніж те, що воно означає, коли використовується як тип повернення. Тепер це означає "вказівник на місце зберігання невідомого типу", який не має нічого спільного зі своїм значенням як "метод, який не повертає жодного значення".

Ми можемо замінити void*як тип вказівника на IntPtr. (І void**сIntPtr* і так далі.) Ми можемо замінити void як тип повернення на "Unit", тип, який має єдине значення, а саме - null. Після цього впровадження CLR може вирішити, що виклик функцій типу типу може оптимізувати його використання регістрів або стеків належним чином, знаючи, що нуль, який "повертається", може бути безпечно ігнорований.

У такому світі вам більше не потрібні окремі Func<A, R>та Action<T>делегати. Action<T>просто Func<T, Unit>.


4
... і Taskє просто a Task<Unit>. Повторне доповнення бібліотечних бітів асинхронного CTP змусило мене по-справжньому побажати цього ...
Джон Скіт

24

Порожнє твердження; . Схильний до помилок, майже завжди друкує помилку, і не дає додаткового значення, яке вже не виражається {}.


7
Не кажучи вже про величезний штраф за продуктивність під 64-розрядним JIT </snark>.
Джессі К. Слікер

7
Порожня заява має покарання за продуктивність? Чому так?
квентин-зірин

22

Небезпечна коваріація на масивах еталонного типу . З увімкненою коваріацією типу IEnumerable<T>, щонайменше, частина потреб у коваріації масиву відпала . (Якби у нас був коваріантний інтерфейс списку лише для читання, він би нам взагалі не потрібен.)


Я зовсім збирався це записати, коли побачив назву питання - ви перемогли мене :(
Кріс Сміт

1
Можливість отримувати посилання на коваріантний масив і безпечно записувати до посилань масиву, які були прочитані з нього , корисна. Якщо, як, що IList<T>передається у спадок від IReadableList<out T>і не є загальним IPemutable, він може підтримувати такі речі, як сортування, але масиви підтримують його легше.
supercat

14

Оператор унар плюс . Найменш корисний оператор усіх часів. Якби нам не довелося тримати його за зворотний співвіт, я б вийняв це із серцебиттям. Хто використовує цю річ, хтось?

(Пояснення: Оператор унарний плюс +x- це не оператор попереднього посилення ++x, не оператор післярозвитку x++і не оператор бінарного додавання x+y.)


1
for (int i = 0; i <стеля; i ++)
Майкл Браун

13
Він не говорить про предінкременте і postincrement операторів: він говорить про одномісний плюс, протилежності негативного знака числа: +1 == 1. Це досить проклято близько до не-оп.
Джессі К. Слікер

8
Це не тільки про вплив на машиночитаемом вихід, він може поліпшити зовнішній вигляд коду для людей: if(a == +1 || a == -1){...}.
Томас Братт

5
@ShuggyCoUK: Що особливо дивно в цьому, це те, що він може завантажуватися . Тому що це трапляється багато. Ви знаєте, як ви пишете якийсь JavaScript, і ви думаєте, людина, я хотів би, щоб JS дозволив мені зробити визначені користувачем унарні плюс оператори семантики, як C # робить .
Ерік Ліпперт

2
@Eric Я не здогадувався, що це можна завантажити. Уау, ви могли з цим
поскудливо

12

Дефолти числових літералів до double

Для більшості бізнес- додатків decimalце все-таки більше підходить ... або, можливо, було б краще просто зняти ідею за замовчуванням і змусити розробника насправді зробити вибір.

(Це "вилучення за замовчуванням" було б доречним і для інших речей. Наприклад, я відмовився переконувати всіх, що класи повинні бути запечатані за замовчуванням, але я підозрюю, що легше переконати людей, що вони повинні думати про це чи слід їх новий клас запечатати чи ні, і зробити це явним.)


Я, можливо, схиляюся до ідентифікації літералів, які мають на увазі значення, яке неможливо точно представити як подвійне /
плаваюче

Якщо вони в Java - віднести їх до священних текстів Джошуа Блоха «дизайн або документ для наслідування , або заборонити його» martinfowler.com/bliki/DesignedInheritance.html IIRC Котлин робить класи ущільнення за замовчуванням, так що галузь рухається в кращий напрямок у цьому відношенні.
Елазар Лейбович

Чому класи повинні бути опечатані?
Джеймс

@James: Точно з тих причин, які дає Джош. Проектування класу, який дає можливість успадкування розумним, послідовним способом, вимагає часу - і це робити, не знаючи, як використовувати спадщину, ще гірше.
Джон Скіт

1
@Pacerier: Подумайте, наприклад, про незмінність. Незапечатаний клас не може претендувати на непорушність, оскільки підкласи можуть вводити незмінність.
Джон Скіт

7

Це скоріше настанова, ніж особливість, але я думаю, що це важливо, оскільки це вже занадто багато вбудовано у свідомості людей як канонічне та найкраще рішення:

Офіційний шаблон для реалізації IDisposable.

Це громіздко і є кращі способи .


6

Я знаю, що між різними класами таймерів є великі відмінності. Але хіба ми не могли позбутися одного чи двох із них?


4

Методи і види Arrayі List<T>які стали застарілими з Linq, наприклад:

  • Array.TrueForAll можна замінити на Enumerable.All
  • Array.FindAll можна замінити на Enumerable.Where
  • List<T>.ConvertAll можна замінити на Enumerable.Select
  • Predicate<T> можна замінити на Func<T, bool>
  • Converter<T,R> можна замінити на Func<T, R>
  • IComparer<T> дійсно повинен бути делегатом Func<T, T, int>

3
Мені це подобається, Predicate<T>тому що він фіксує наміри щодо використання функції та економить крихітний шматочок введення тексту.
Зебі

2

Негенеричні делегати Як і узагальнені колекції, негенеріальні делегати марні тепер, коли у нас є серії Func та Action. І я б відрізав варіанти за трьома параметрами. Якщо у вас більше трьох параметрів, створіть структуру і використовуйте її як єдиний параметр. Декларація конкретного делегата для обробки подій не дуже ДУХА.


3
Як би ви визначили делегата до методу, який приймає посилання з Action або Func? Як би ви визначили комбінатор з Func? Тобто, немає ніякого способу сказати "делегат DD (D d);" з Функ.
Ерік Ліпперт

2
хммм ... я стою виправлений. Ось чому я залишаю роботу зі створення інструментів, якими я користуюся у ваших здібних руках;)
Майкл Браун

@EricLippert: Я хотів би бачити спеціальний клас делегатів, який би магією CLR містив делегатів «кожної» сутності та комбінації параметрів значення / еталону [пошук делегата в магічному класі з відповідним форматуванням імені створив би type], і всі делегати належного підпису успадковують це. Код, який хоче конкретного делегата, все ще вимагатиме точного типу, але код, який хоче певного підпису, може використовувати магічне ім'я.
supercat

-1

asmx Web Services

Я думаю, що вони досить застарілі з WCF сьогодні.


6
Так, але іноді набагато простіше бавитися. . .
Wyatt Barnett

-2

Winforms
Було б непогано пересуватись між двома платформами настільних ПК. WPF - це те, куди йдуть справи, тому неприємно мати повне надмірність на рівні платформи.


Winforms здається набагато стабільнішим, швидшим та менш
глючним,

Коли вам просто потрібно зламати невеликий додаток для настільних ПК, WPF - це великий зайвий рівень.
Kyralessa

Здається, між WPF стало досить застарілим на користь WinRT. Однак мені здається, що Winforms є більш живим, ніж WPF в розвитку бізнесу. Дивіться також stackoverflow.com/questions/913417/…
Doc Brown
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.