C# (.NET) [закрытые] недостатки дизайна

Swift 4

    /// Takes the screenshot of the screen and returns the corresponding image
    ///
    /// - Parameter shouldSave: Boolean flag asking if the image needs to be saved to user's photo library. Default set to 'true'
    /// - Returns: (Optional)image captured as a screenshot
    open func takeScreenshot(_ shouldSave: Bool = true) -> UIImage? {
        var screenshotImage :UIImage?
        let layer = UIApplication.shared.keyWindow!.layer
        let scale = UIScreen.main.scale
        UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);
        guard let context = UIGraphicsGetCurrentContext() else {return nil}
        layer.render(in:context)
        screenshotImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        if let image = screenshotImage, shouldSave {
            UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil)
        }
        return screenshotImage
    }

Обновлено для Swift 2

Код, который вы предоставляете, работает, но не позволяет вы должны захватить NavigationBar и StatusBar на снимке экрана. Если вы хотите сделать снимок экрана вашего устройства, который будет включать в себя NavigationBar, вы должны использовать следующий код:

func screenShotMethod() {
    let layer = UIApplication.sharedApplication().keyWindow!.layer
    let scale = UIScreen.mainScreen().scale
    UIGraphicsBeginImageContextWithOptions(layer.frame.size, false, scale);

    layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let screenshot = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    UIImageWriteToSavedPhotosAlbum(screenshot, nil, nil, nil)
}

С помощью этого кода:

  • При первом запуске приложения и вызове этого метода устройство iOS попросит вас сохранить ваше изображение в кадре камеры.
  • Результатом этого кода будет изображение .JPG.
  • В конечном изображении StatusBar не будет отображаться.
85
задан 3 revs, 3 users 57% 1 July 2015 в 18:58
поделиться

31 ответ

Я полностью согласен с этим сообщением (для тех, кто жалуется на отсутствие ToString, есть атрибут отладчика для предоставить собственный формат для вашего класса).

В верхней части приведенного выше списка я бы также добавил следующие разумные запросы:

  1. ссылочные типы, не допускающие значения NULL, в качестве дополнения к типам значений, допускающим значение NULL,
  2. разрешают переопределение пустой конструктор struct
  3. позволяет ограничениям универсального типа указывать запечатанные классы,
  4. Я согласен с другим автором, который запрашивал произвольные сигнатуры конструктора при использовании в качестве ограничений, т.е. где T: новый (строка) , или где T: новый (строка, int)
  5. Я также согласен с другим постером здесь об исправлении событий, как для пустых списков событий, так и в параллельной настройке (хотя последнее сложно),
  6. операторы должны определяться как методы расширения, а не как статические методы класса (или не только как статические методы, по крайней мере),
  7. разрешают статические свойства и методы для интерфейсов (Java имеет это, но C # нет),
  8. разрешает инициализацию событий в инициализаторах объектов (только поля и свойства являются в настоящее время разрешено),
  9. почему синтаксис «инициализатор объекта» можно использовать только при создании объекта? Почему бы не сделать его доступным в любое время, т.е. var e = new Foo (); e {Bar = baz};
  10. исправить поведение квадратичного перечисления ,
  11. все коллекции должны иметь неизменяемые моментальные снимки для итерации (т.е. изменение коллекции не должно приводить к недействительности итератора),
  12. кортежи легко добавить, но эффективный закрытый алгебраический тип, такой как « Either », - нет, поэтому мне бы хотелось каким-нибудь способом объявить закрытый алгебраический тип и обеспечить полное сопоставление с образцом на это (в основном первоклассная поддержка шаблона посетителя, но гораздо более эффективная); так что просто возьмите перечисления, расширьте их с помощью исчерпывающей поддержки сопоставления с образцом и не допускайте недопустимых случаев
  13. . Мне бы хотелось поддерживать сопоставление с образцом в целом, но, по крайней мере, для тестирования типов объектов; Мне также нравится синтаксис переключателя, предложенный в другом сообщении здесь
  14. . Я согласен с другим сообщением, что классы System.IO , такие как Stream , несколько плохо спроектированы; любой интерфейс, который требует от некоторых реализаций выброса NotSupportedException , является плохой конструкцией,
  15. IList должен быть намного проще, чем он есть; на самом деле это может быть верно для многих конкретных интерфейсов коллекций, таких как ICollection ,
  16. слишком много методов генерируют исключения, например, IDictionary,
  17. Я бы предпочел форму проверенных исключений. чем то, что доступно в Java (см. исследования систем типов и эффектов, чтобы узнать, как это можно сделать),
  18. исправить различные раздражающие угловые случаи в разрешении перегрузки универсального метода; например, попробуйте предоставить два перегруженных метода расширения, один из которых работает со ссылочными типами, а другой - с типами, допускающими значение NULL, и посмотрите, как это нравится вашему выводу типа,
  19. предоставляет способ безопасного отражения имен полей и членов для интерфейсов например INotifyPropertyChanged , которые принимают имя поля в виде строки; вы можете сделать это, используя метод расширения, который принимает лямбда с выражением MemberExpression , т.е. () => Foo , но это не очень эффективно,
    • Обновление: в C # 6.0 добавлен оператор nameof () для имен отдельных элементов, но он не работает в универсальных шаблонах ( nameof (T) == "T" вместо фактическое имя аргумента типа: вам все равно нужно выполнить typeof (T) .Name )) - и это не позволит вам получить строку «путь», например nameof (this.ComplexProperty. Value) == "Value" , ограничивающее его возможные приложения.
  20. разрешает операторы в интерфейсах и заставляет все типы номеров ядра реализовывать IArithmetic ; также возможны другие полезные общие интерфейсы операторов
  21. , которые затрудняют изменение полей / свойств объекта или, по крайней мере, позволяют аннотировать неизменяемые поля и заставляют средство проверки типов применять его (просто рассматривайте это как свойство только для геттера. блин, это не сложно!); на самом деле, унифицировать поля и свойства более разумным способом, поскольку нет смысла иметь и то, и другое; Автоматические свойства C # 3.0 - это первый шаг в этом направлении, но они недостаточны,
    • Обновление: в то время как в C # было ключевое слово readonly , а в C # 6.0 добавлены автоматические свойства только для чтения, хотя это не так строго, как настоящая языковая поддержка неизменяемых типов и значений.
  22. упрощение. объявление конструкторов; Мне нравится подход F #, но другой пост здесь, который требует просто «новый» вместо имени класса, по крайней мере, лучше,

Полагаю, на данный момент этого достаточно. Это все раздражения, с которыми я столкнулся на прошлой неделе. Я, вероятно, мог бы продолжать в течение нескольких часов, если бы действительно задумался. C # 4.0 уже добавляет именованные, необязательные аргументы и аргументы по умолчанию, что я решительно одобряю.

Теперь для одного необоснованного запроса:

  1. было бы действительно, действительно хорошо, если бы C # / CLR мог поддерживать полиморфизм конструктора типов, т.е. дженерики вместо дженериков,

Довольно, пожалуйста? : -)

39
ответ дан 24 November 2019 в 08:07
поделиться
  1. я не большой поклонник Потока, StringWriter, StringReader, TextReader, классов TextWriter..., это просто не интуитивно, что что.
  2. IEnumerable. Сброс, выдающий исключение для итераторов. У меня есть некоторые сторонние компоненты, которые всегда называют сброс, когда связано с данными, требует, чтобы я бросил к списку сначала для использования их.
  3. Сериализатор Xml должен был сериализировать элементы IDictionary
  4. , я полностью забыл о HttpWebRequest & API FTP, что боль в моем.... (благодарит за комментарий Nicholas для напоминания мне о this:-)

Редактирование
5. Другое мое раздражение то, как Система. Отражение. BindingFlags, имеет различное использование в зависимости от метода Ваше использование. В FindFields, например, что имеют в виду CreateInstance или SetField? Это - случай, где они перегрузили значение позади этого перечисления, которое сбивает с толку.

20
ответ дан 4 revs 24 November 2019 в 08:07
поделиться

Я действительно удивлен, что я первый для упоминания этого:

введенные наборы данных ADO.NET не представляют nullable столбцы как свойства nullable типов. Необходимо быть в состоянии записать это:

int? i = myRec.Field;
myRec.Field = null;

Вместо этого необходимо записать это, которое просто глупо:

int? i = (int?)myRec.IsFieldNull() ? (int?)null : myRec.Field;
myRec.SetFieldNull();

Это было раздражающим в.NET 2.0, и это является еще более раздражающим теперь, когда необходимо использовать возню как вышеупомянутое в хороших аккуратных запросах LINQ.

Это является также раздражающим, что сгенерированный Add<TableName>Row метод столь же нечувствителен к понятию nullable типов. Тем более поэтому начиная со сгенерированного TableAdapter методы не.

нет много в.NET, которая заставляет меня чувствовать, что команда разработчиков заявила "Хорошо, мальчики, мы достаточно близки - поставляют его!" Но это уверенное делает.

20
ответ дан Robert Rossney 24 November 2019 в 08:07
поделиться

Я не понимаю, что Вы не можете сделать

где T: новый (U)

, Таким образом, Вы объявляете, что универсальный тип T имеет конструктора не по умолчанию.

редактирование:

я хочу сделать это:

public class A 
{
    public A(string text) 
    {

    }
}


public class Gen<T> where T : new(string text) 
{

}
29
ответ дан 2 revs 24 November 2019 в 08:07
поделиться

Маленькое домашнее животное C# peev - конструкторы использует C++ / синтаксис Java наличия конструктора быть тем же именем как класс.

New() или ctor() было бы намного более хорошим.

И уверенный, инструменты, такие как coderush делают это меньшим количеством проблемы для переименования классов, но от удобочитаемости POV, Новый (), обеспечивает большую ясность.

44
ответ дан 2 revs 24 November 2019 в 08:07
поделиться
  • Reset() метод на IEnumerator<T> был ошибкой (для блоков итератора, спецификация языка даже требования , что это выдает исключение)
  • отражательные методы, что возвращаемые массивы были, в представлении Eric, ошибка
  • , ковариантность массива была и остается причудой; по крайней мере, в C# 4.0/.NET 4.0 это сделано правильно для IEnumerable[<T>]
  • ApplicationException, скорее впал в немилость - который был ошибкой?
  • синхронизируемые наборы - хорошая идея, но не обязательно полезный в действительности: обычно необходимо ли синхронизироваться [приблизительно 1 119] операции (Contains, тогда Add), таким образом, набор, который синхронизирует отличные операции, не является всем, чем полезный
  • [еще 1126] использование, возможно, было сделано из using / lock шаблон - возможно, разрешение им совместно использовать допускающее повторное использование (расширяемый?) синтаксис; можно моделировать это путем возврата IDisposable и использования using, но это, возможно, было более ясно
  • блоки итератора: никакой простой способ проверить аргументы загодя (а не лениво). Несомненно, можно записать два цепочечных метода, но это ужасно
  • , более простая неизменность была бы хороша; C# 4.0 помогает немного , но не совсем достаточно
  • никакой "этот параметр касательно типа не может быть пустой" поддержкой - хотя контракты (в 4,0) помогают с этим несколько. Но синтаксис как [1 110] (который вводит пустую проверку / throw) был бы хорош (контраст по отношению к [1 112] и т.д.)
  • отсутствие поддержки операторов и конструкторов не по умолчанию с дженериками; C# 4.0 решает это немного с [1 113], или можно включить его как это
<час>
  • переменная итератора, объявляемая внешний , в то время как в foreach расширение, означая, что anon-methods/lambdas получают единственную переменную, а не один на повторение (болезненный с поточной обработкой/асинхронной/и т.д.)
72
ответ дан 5 revs, 2 users 64% 24 November 2019 в 08:07
поделиться

TextWriter основа класс StreamWriter. wtf?

, Который всегда смущает меня до крайности.

60
ответ дан 2 revs, 2 users 80% 24 November 2019 в 08:07
поделиться

Переменные с неявно определенным типом были реализованы плохо IMO. Я знаю, что необходимо действительно только использовать их при работе с выражениями Linq, но это является раздражающим, что Вы не можете объявить их за пределами локального объема.

Из MSDN:

  • var может только использоваться, когда локальная переменная объявляется и инициализируется в том же операторе; переменная не может быть инициализирована к пустому указателю, или группе метода или анонимной функции.
  • var не может использоваться на полях в объеме класса.
  • Переменные, объявленные при помощи var, не могут использоваться в выражении инициализации. Другими словами, это выражение законно: интервал i = (я = 20); но это выражение производит ошибку времени компиляции: var i = (я = 20);
  • Несколько переменных с неявно определенным типом не могут быть инициализированы в том же операторе.
  • , Если тип назвал var, находится в объеме, то ключевое слово var решит к тому имени типа и не будет рассматриваться как часть неявно введенного локального объявления переменных.

причина я думаю, что это - плохая реализация, то, что они называют его var, но это - длинный путь от того, чтобы быть вариантом. Это - действительно просто синтаксис стенографии для того, чтобы не иметь необходимость ввести полностью имя класса (кроме тех случаев, когда используемый с Linq)

0
ответ дан 2 revs 24 November 2019 в 08:07
поделиться

Одна вещь, которая убрала галочку во мне в 1.x, состояла в том, когда использование эти System.Xml.XmlValidatingReader, ValidationEventHandler ValidationEventArgs не представляет лежание в основе XmlSchemaException (отметил внутренний), который имеет всю полезную информацию как linenumber и position. Вместо этого Вы, как ожидают, будете анализировать это из свойства Строки сообщения или использовать отражение для раскапывания его. Не настолько хороший, когда Вы хотите возвратить более санированную ошибку конечному пользователю.

2
ответ дан Kev 24 November 2019 в 08:07
поделиться

.Parameters. Добавьте (), метод на SqlCommand в V1 платформы был ужасно разработан - одна из перегрузок в основном не работала бы, если бы Вы передали в параметре со значением (интервал) 0 - ведомый к ним создающий.Parameters. AddWithValue () метод на классе SqlCommand.

3
ответ дан 2 revs 24 November 2019 в 08:07
поделиться
  • Быть в состоянии вызвать дополнительный метод на пустую переменную является спорным, например,

    объект a=null; a. MyExtMethod ();//это является вызываемым, примите где-нибудь, что это определило MyExtMethod

    , Это могло быть удобно, но это неоднозначно по темам исключения нулевой ссылки.

  • Одно именование 'дефект'. 'C' "конфигурации" в System.configuration.dll должен капитализироваться.

  • Обработка исключений. Исключение должно быть насильственно поймано или выдано как в Java, компилятор должен проверить его во время компиляции. Пользователи не должны полагаться на комментарии для получения информации об исключениях в рамках целевого вызова.

3
ответ дан 2 revs 24 November 2019 в 08:07
поделиться

Microsoft не исправит очевидные ошибки в платформе и не обеспечит рычаги, таким образом, конечные пользователи смогут зафиксировать их.

кроме того, нет никакого пути к исполняемым файлам.NET двоичного патча во времени выполнения и никакого способа определить частные версии библиотек платформы.NET без двоичного файла, исправляющего собственные библиотеки (для прерывания вызова загрузки), и ILDASM не является распространяемым файлом, таким образом, я не могу автоматизировать патч так или иначе.

3
ответ дан Joshua 24 November 2019 в 08:07
поделиться

Дополнительные методы хороши, но они - ужасный способ решить проблемы, которые, возможно, были решены инструмент для очистки с реальным mixins (взгляд на рубин для наблюдения то, что я говорю о), на предмет mixins. Действительно хороший способ добавить их к языку состоял бы в том, чтобы позволить дженерикам использоваться для наследования. Это позволяет Вам расширять существующие классы хорошим объектно-ориентированным способом:

public class MyMixin<T> : T
{
    // etc...
}

это может использоваться как это для расширения строки, например:

var newMixin = new MyMixin<string>();

Это намного более мощно, чем дополнительные методы, потому что это позволяет Вам переопределенным методам, например, обертывать их позволяющий подобную AOP функциональность в языке.

Извините за напыщенную речь:-)

4
ответ дан Mendelt 24 November 2019 в 08:07
поделиться

Путем мы используем свойства, иногда раздражает меня. Мне нравится думать о них как об эквиваленте getFoo Java () и setFoo () методы. Но они не.

, Если Инструкции по Использованию Свойства состояние, что свойства должны быть в состоянии быть установленными в любом порядке так сериализация, может работать, тогда они бесполезны для разовой методом set проверки. Если Вы происходите из среды, где Вам нравится препятствовать объекту позволить себе когда-либо входить в недопустимое состояние, то свойства не являются Вашим решением. Иногда мне не удается видеть, как они лучше, чем общедоступные участники, так как мы так ограничены в том, какие виды вещей мы , предположил делать в свойствах.

С этой целью, я всегда отчасти желал (это главным образом думает вслух здесь, я просто вид желания, я мог сделать что-то вроде этого), что я мог расширить синтаксис свойства так или иначе. Вообразите что-то вроде этого:


private string password;

public string Password
{
    // Called when being set by a deserializer or a persistence
    // framework
    deserialize
    {
       // I could put some backward-compat hacks in here. Like
       // weak passwords are grandfathered in without blowing up
       this.password = value;
    }
    get
    {
       if (Thread.CurrentPrincipal.IsInRole("Administrator"))
       {
           return this.password;
       }
       else
       {
           throw new PermissionException();
       }
    }
    set
    {
       if (MeetsPasswordRequirements(value))
       {
           throw new BlahException();
       }
       this.password = value;
    }
    serialize
    {
        return this.password;
    }
}

я не уверен, полезно ли это или на что это получающий доступ те были бы похожи. Но мне просто жаль, что я не мог сделать больше со свойствами и действительно рассматривать их, любят, добираются и методы установки.

4
ответ дан Nicholas Piasecki 24 November 2019 в 08:07
поделиться

Уже добавить к длинному списку правильных замечаний, сделанных другими:

  • DateTime.Now == DateTime.Now в большинстве, но не всех случаях.

  • String то, которое неизменно, имеет набор опций для конструкции и управления, но StringBuilder (который изменяем), не делает.

  • Monitor.Enter и Monitor.Exit должны были быть методы экземпляра, таким образом, вместо newing конкретный объект для блокировки, Вы могли новый Monitor и соединять это.

  • Деструкторы никогда нельзя было называть деструкторами. Спецификация ECMA называет их финализаторами, который намного менее сбивает с толку толпу C++, но спецификация языка все еще называет их деструкторами.

5
ответ дан 2 revs 24 November 2019 в 08:07
поделиться

0 слабого освещения улиц как перечисление

особенности перечисления: http://blogs.msdn.com/abhinaba/archive/2007/01/09/more-peculiarites-of-enum.aspx

, как проиллюстрировано этим хорошим примером: http://plus.kaist.ac.kr/~shoh/postgresql/Npgsql/apidocs/Npgsql.NpgsqlParameterCollection.Add_overload_3.html

мое предложение, помещенное, подают знак хорошему использованию:

вместо:

, если ((myVar & MyEnumName. ColorRed)! = 0)

использование это:

, если ((myVar & MyEnumName. ColorRed)! = @0)

5
ответ дан Michael Buen 24 November 2019 в 08:07
поделиться

Некоторые классы реализуют интерфейсы, но они не реализуют многие методы того интерфейса, например, Массив реализует IList, но 4 из 9 методов бросают NotSupportedException http://msdn.microsoft.com/en-us/library/system.array_members.aspx

7
ответ дан 2 revs 24 November 2019 в 08:07
поделиться
  1. Система. Объект класс:

    • Равняется и GetHashCode - не, все классы сопоставимы или hashable, должен быть перемещен в интерфейс. IEquatable или IComparable (или подобный) приходят на ум.

    • ToString - не все классы могут быть преобразованы в строку, должен быть перемещен в интерфейс. IFormattable (или подобный) приходит на ум.

  2. ICollection. Свойство SyncRoot:

    • Способствует плохому дизайну, внешняя блокировка почти всегда более полезна.
  3. Дженерики должны были быть там с начала:

    • Система. Наборы пространство имен содержат много более или менее устаревших классов и интерфейсов.
13
ответ дан dalle 24 November 2019 в 08:07
поделиться

Ужасное (и довольно невидимый для большинства людей) O (N^2) поведение вложенных/рекурсивных итераторы .

я вполне разрушен, что они знают об этом, знают , как зафиксировать его , но это не просматривается как наличие достаточного приоритета заслужить включение.

я работаю с деревом как структуры все время и имею для исправления кода в других отношениях умных людей, когда они непреднамеренно представляют очень дорогие операции таким образом.

красота "урожая foreach' состоит в том, что более простой, более легкий синтаксис поощряет корректный, производительный код. Это "яма успеха" , что я думаю, что они должны стремиться к прежде, чем добавить новые опции для долгосрочного успеха платформы.

9
ответ дан ShuggyCoUk 24 November 2019 в 08:07
поделиться

События в C#, где Вы имеете к явной проверке на слушателей. Разве это не было точкой с событиями, для широковещательной передачи тому, кто бы ни, оказывается, там? Даже если нет никого?

10
ответ дан Thomas Eyde 24 November 2019 в 08:07
поделиться

Мы знаем так много о право методы OO. Разъединение, программирование согласно контракту, предотвращение неподходящего наследования, соответствующего использования исключений, открываются/закрывают принципал, замещаемость Liskov, и так далее. Любой все же.Net платформы не используют лучшие практики.

мне единственный самый большой дефект в дизайне.Net не стоит на плечах гигантов; продвижение меньше, чем идеальные парадигмы программирования к массам программистов, которые используют их платформы .

, Если MS обратил внимание на это, мир разработки программного обеспечения, возможно, сделал большие прыжки с точки зрения качества, устойчивости и масштабируемости в это десятилетие, но увы, это, кажется, регрессирует.

10
ответ дан Daniel Paull 24 November 2019 в 08:07
поделиться

Мне не нравится оператор переключения C#.

я хотел бы что-то вроде этого

switch (a) {
  1    : do_something;
  2    : do_something_else;
  3,4  : do_something_different;
  else : do_something_weird; 
}

Так больше повреждений (легкий забыть) и возможность к отдельным от запятой различным значениям.

11
ответ дан tuinstoel 24 November 2019 в 08:07
поделиться

Некоторым людям (независимые поставщики программного обеспечения) жаль, что Вы не могли скомпилировать его в машинный код во время изготовления, и связывать его, для создания собственного исполняемого файла, которому не нужно dotNet время выполнения.

11
ответ дан 2 revs, 2 users 67% 24 November 2019 в 08:07
поделиться

Одна из вещей, которая раздражает меня, Predicate<T> != Func<T, bool> парадокс. Они - оба делегаты типа T -> bool, и все же они не совместимое присвоение.

12
ответ дан Greg Beech 24 November 2019 в 08:07
поделиться

Статические участники и вложенные типы в интерфейсах.

Это особенно полезно, когда у интерфейсного участника есть параметр типа, который характерен для интерфейса (, например, enum). Было бы хорошо вложить перечислимый тип в интерфейсном типе.

7
ответ дан Jay Bazuzi 24 November 2019 в 08:07
поделиться

Я не знаю, что пошел бы, до для высказывания это - недостаток дизайна, но было бы действительно хорошо, если Вы могли бы вывести лямбда-выражение таким же образом, Вы можете в VB:

VB:

Dim a = Function(x) x * (x - 1)

C#

было бы хорошо, если мог сделать это:

var a = x => x * (x - 1);

Вместо того, чтобы иметь необходимость сделать это:

Func<int, int> a = x => x * (x - 1);

я понимаю, что это не намного более длинно, но в Коде Играют в гольф каждый счетчики символов damnit! Разве они не принимают это во внимание, когда они разрабатывают эти языки программирования?:)

15
ответ дан BenAlabaster 24 November 2019 в 08:07
поделиться

Не любите его, что Вы не можете использовать значения одного перечисления в другом перечислении, например:

    enum Colors { white, blue, green, red, black, yellow }

    enum SpecialColors { Colors.blue, Colors.red, Colors.Yellow } 
1
ответ дан tuinstoel 24 November 2019 в 08:07
поделиться

Ужасно опасный характер событий по умолчанию. Тот факт, что вы можете вызвать событие и оказаться в несогласованном состоянии из-за удаления подписчиков, просто ужасен. См. отличные статьи Джона Скита и Эрика Липперта для получения дополнительной информации по этой теме.

6
ответ дан 24 November 2019 в 08:07
поделиться
  • null везде.

  • const нигде.

  • API непоследовательны, например, мутирование массива возвращает void, но добавление к StringBuffer возвращает тот же мутируемый StringBuffer.

  • Интерфейсы коллекций несовместимы с неизменяемыми структурами данных, например, Add в System.Collections.Generic.IList<_> не может вернуть результат.

  • Отсутствие структурной типизации, поэтому вы пишете System.Windows.Media.Effects.SamplingMode.Bilinear вместо просто Bilinear.

  • Мутабельный интерфейс IEnumerator реализован классами, когда он должен быть неизменяемым struct.

  • Равенство и сравнение - полная неразбериха: у вас есть System.IComparable и Equals, но также есть System.IComparable<_>, System.IEquatable, System.Collections. IComparer, System.Collections.IStructuralComparable, System.Collections.IStructuralEquatable, System.Collections.Generic.IComparer and System.Collections.Generic.IEqualityComparer.

  • Кортежи должны быть структурами, но структуры излишне препятствуют устранению хвостовых вызовов, поэтому один из самых распространенных и фундаментальных типов данных будет выделяться без необходимости и разрушать масштабируемый параллелизм.

6
ответ дан 24 November 2019 в 08:07
поделиться

CLR (и поэтому C#) не поддерживает Множественное наследование, и ASP.NET наполнен повреждениями LSP...

Те - мое "избранное"...

я мог, вероятно, найти больше ошибок, но те - те, мне не нравится больше всего...!!: (

-1
ответ дан Thomas Hansen 24 November 2019 в 08:07
поделиться