Почему dotnet char.IsLower () является статическим методом?

Похоже, это противоречит всем руководящим принципам дизайна. Статический метод, который принимает единственный аргумент типа T, обычно должен быть просто методом-членом.

Это так странно, что мне пришлось опубликовать StackOverflow вопрос, чтобы понять, что IsUpper существует (поскольку он не отображался в автозаполнении)

Редактировать

Я понимаю, что мое предыдущее заявление требует небольшого пояснения. Пример хорошего дизайна - String.ToLower (). Вместо того, чтобы прототипировать его как static void ToLower (String foo), это метод-член. Совершенно очевидно (по крайней мере, для меня), что то же самое должно происходить и с char.IsLower ().

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
762
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

См. Также вопрос это.

Краткая версия - в исходной среде IDE возникли проблемы с появлением intellisense при вызове из строкового литерала (и я предполагаю, что литералы char тоже). Поэтому дизайнеры сделали методы статическими, чтобы обойти эту проблему.

РЕДАКТИРОВАНИЕ: Здесь я немного разглагольствовал о дизайнерах .NET, поддавшихся давлению со стороны дизайнеров IDE. Но, увидев ответ Попа на этот вопрос, я менее уверен в этом.

EDIT2: Тим в комментариях спросил, знаем ли мы, что это правда, или это просто предположение. Мне не удалось найти точную ссылку на эту проблему, но я нашел статью 2002 года, в которой говорилось об ошибке intellisense в строковом литерале. Это примерно на полпути вниз по странице это.

это большое предположение. Знаем ли мы на самом деле? Можем ли мы это подтвердить, или это всего лишь предположение?

Tim 23.12.2008 19:32

В этом объяснении гораздо больше смысла, чем в объяснении Тима.

Constantin 23.12.2008 19:43

Методы класса String и методы stuctures / primiteves не имеют ничего общего. Причина не в этом. Причина в безопасности потоков. Сделать метод статическим - это простой способ сделать его потокобезопасным, поскольку он получает копию структуры.

Pop Catalin 23.12.2008 19:52

@Pop единственное, что у них общего, - это язык, определяющий для них литералы, с которыми у IDE были проблемы. В этом смысле строка и символы (а также целые числа, числа с плавающей запятой, десятичные дроби и т. д.) Одинаковы.

Cameron MacFarland 23.12.2008 19:57

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

Pop Catalin 23.12.2008 20:07

Методы экземпляра в строках получают ссылку this, которую нельзя изменить. Методы экземпляра примитивов и структур получают указатель на структуру, и этот указатель указывает на энергозависимую память.

Pop Catalin 23.12.2008 20:08

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

Tim 23.12.2008 21:03

На мой взгляд, это имеет смысл.

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

double d = 100.0;
Console.WriteLine("Square root of d is " + d.Sqrt());

Это уменьшило бы «Сплоченность» в плане ОО-дизайна, что не является хорошей практикой. Было бы лучше разделить эту ответственность на класс Math.

double d = 100.0;
Console.WriteLine("Square root of d is " + Math.Sqrt(d));
Ответ принят как подходящий

Методы экземпляра в структурах не являются потокобезопасными. Статические методы, напротив, находятся.

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

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

Смотри здесь похожий вопрос.

Почему IsNan - это статический метод класса Double, а не свойство экземпляра?

В данном случае это не имеет значения. IsLower не изменяет значение, с которым работает.

Daniel Earwicker 23.12.2008 19:55

Нет, но он использует значение, чтобы что-то определить (в данном случае). Если IsLower не является потокобезопасным, то многопоточный код может привести к тому, что IsLower вернет неправильный ответ.

Cameron MacFarland 23.12.2008 20:00

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

Pop Catalin 23.12.2008 20:00

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

Daniel Earwicker 23.12.2008 20:42

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

Pop Catalin 23.12.2008 20:45

Да, но что, если бы значение в течение было изменено копией? Для нетривиальной структуры это возможно. А для ToLower он считывает значение только один раз, поэтому это не имеет никакого значения.

Daniel Earwicker 23.12.2008 20:52

@Jay Bazuzi: если вы перейдете по ссылке, вы увидите пример того, как даже неизменяемые структуры не могут иметь потокобезопасные методы экземпляра. Если структура может быть скопирована (даже если она неизменна) и доступна через указатель (как это делает метод экземпляра), то это «не потокобезопасный».

Pop Catalin 23.12.2008 20:55

@Earwicker, если значение было изменено во время копирования, то состояние гонки находится вне метода, а не внутри него. Условия конкуренции внутри методов инфраструктуры могут иметь различные разветвления, такие как нарушения безопасности и неопределенное поведение во время выполнения. Гонки в вашем коде могут привести только к ошибкам.

Pop Catalin 23.12.2008 20:58

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

Daniel Earwicker 23.12.2008 21:04

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

Pop Catalin 23.12.2008 21:57

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

Pop Catalin 23.12.2008 21:58

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

Daniel Earwicker 23.12.2008 22:07

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

Daniel Earwicker 23.12.2008 22:08

Кроме того, метод экземпляра для типа значения может точно имитировать поведение статического элемента, просто создавая копию this в начале. Тогда он ведет себя как статический метод. Так что переходить на статику все равно не нужно. Сложите все это вместе, и я не понимаю, в чем проблема.

Daniel Earwicker 23.12.2008 22:09

@Earwicker: Когда метод экземпляра копирует значение, можете ли вы гарантировать, что значение, которое он копирует, является значением до или после изменения значения в другом потоке?

Cameron MacFarland 24.12.2008 04:37

Нет - и то же самое верно, когда статический метод копирует значение.

Daniel Earwicker 24.12.2008 20:53

Другие вопросы по теме