Подтвердить что ты не робот

С# classes - Почему так много статических методов?

Я новичок в С#, так что несите меня.

Одна из первых вещей, которые я заметил о С#, состоит в том, что многие из этих классов являются статическими. Например...

Почему это:

Array.ForEach(arr, proc)

вместо:

arr.ForEach(proc)

И почему это:

Array.Sort(arr)

вместо:

arr.Sort()

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

Ответ 3

Также см. это правило из FXCOP

CA1822: Отметить участников как статические

Описание правила

Члены, которые не имеют доступа к данным экземпляра или вызовам экземпляров, могут быть помечены как статические (Shared в Visual Basic). После того, как вы отметите методы как статические, компилятор будет генерировать не виртуальные сайты этих членов. Испускание не виртуальных сайтов вызова предотвратит проверку на runtime для каждого вызова, который гарантирует, что текущий указатель объекта не имеет значения. Это может обеспечить измеримое усиление производительности для чувствительный к производительности код. В некоторых случаях отказ доступа к текущий экземпляр объекта представляет проблему корректности.

Ответ 4

Классические мотивы против статики:

  • Трудно проверить
  • Небезопасный поток
  • Увеличение размера кода в памяти

1) У С# есть несколько доступных инструментов, которые делают тестирование статических методов относительно легким. Сравнение инструментов С# mocking, некоторые из которых поддерживают статическое издевательство: https://stackoverflow.com/questions/64242/rhino-mocks-typemock-moq-or-nmock-which-one-do-you-use-and-why

2) Существуют хорошо известные, эффективные способы создания/логического создания статических объектов без потери безопасности потоков на С#. Например, реализуя шаблон Singleton со статическим классом в С# (вы можете перейти к пятому методу, если неадекватные параметры вас несут): http://www.yoda.arachsys.com/csharp/singleton.html

3) Как упоминает @K-ballo, каждый метод способствует размеру кода в памяти на С#, а не методам экземпляра, получающим специальное лечение.

Тем не менее, 2 конкретных примера, которые вы указали, являются просто проблемой поддержки устаревшего кода для статического класса Array до того, как дженерики и какой-то другой сахар кода были введены еще в С# 1.0 дня, как сказал @Inerdia. Я пытался ответить, предполагая, что у вас больше кода, на который вы ссылались, возможно, включая внешние библиотеки.

Ответ 5

Воспринимаемая функциональность.

Функции "Утилиты" в отличие от большей части функциональности OO предназначены для таргетинга.

Подумайте о случае с коллекциями, I/O, математикой и почти всей утилитой.

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

Мы получаем довольно близко, но все еще не очень OO, чтобы передавать коллекции (где ваша бизнес-логика? где вы помещаете методы, которые управляют вашей коллекцией, и другие маленькие части или две данные, которые вы всегда просматриваете с помощью это?)

То же самое с числами и математикой. Трудно иметь Integer.sqrt() и Long.sqrt() и Float.sqrt() - это просто не имеет смысла, а также не "новый Math(). Sqrt()". Есть много областей, которые он просто плохо моделирует. Если вы ищете математическое моделирование, то OO может быть не лучшим выбором. (Я сделал довольно полный класс "Complex" и "Matrix" на Java и сделал их довольно OO, но, поскольку они действительно научили меня некоторым ограничениям OO и Java, я закончил "Использование" классов из Groovy в основном)

Я никогда не видел ничего нигде НИКОГДА, как OO, для моделирования вашей бизнес-логики, демонстрируя связи между кодом и управляя вашими отношениями между данными и кодом.

Таким образом, мы возвращаемся к другой модели, когда имеет смысл сделать это.

Ответ 6

Класс Array не является общим и не может быть полностью родовым, потому что это нарушит совместимость. Там какая-то магия происходит там, где массивы реализуют IList<T>, но это только для одномерных массивов с нижней границей массивов 0 - "list-ish".

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