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

Вид: 20516|Ответ: 0

[Чаевые] Сорок семь способов оптимизировать программу на C#

[Скопировать ссылку]
Опубликовано 15.03.2018 10:41:59 | | |

1. Заменить доступные поля атрибутами

1、. .NET data binding поддерживает только привязку данных, и преимущества привязки данных можно получить с помощью атрибутов.
2. В режиме «получить и настроить доступ к свойству» можно использовать блокировку для добавления поддержки многопоточности.

2. readonly (константа выполнения времени) и const (константа по времени компиляции)

1. Const может использоваться только для примитивных типов, enums и строк, тогда как readonly может быть любым типом;
2. CONST будет заменён определённой константой во время компиляции, так что если в ссылке используются значения Const, и Readonly значения, переход на readonly изменит первоначальную цель дизайна — необходимость перекомпиляции изменённой сборки для повторного ссылания на новое постоянное значение.
3. Const эффективнее только для чтения, но теряет гибкость применения.

3. IS и AS

1. Оба варианта являются преобразованиями типов во время выполнения, так как операторы могут использоваться только в эталонных типах, а is — в значениях и эталонных типах;
2. Обычно используют IS для определения типа, а затем выбирают как или сильный оператор преобразования типов (преобразование, определённое оператором).

4. ConditionalAttribute вместо #if #endif条件编译

1. ConditionalAttribute используется только на уровне метода, а другие элементы, такие как типы, атрибуты и т.д., недопустимы. И #if #endif则不受此限制;
2. ConditionalAttribute может добавлять несколько операций OR (OR) для условий компиляции, и #if #endif则可以添加与(AND) [здесь можно полностью определить как отдельный символ];
3. Определение ConditioanlAttribute можно использовать в отдельном методе, чтобы сделать программу более гибкой.

5. Предоставить метод ToString()

1. Он может предоставлять пользователям подробную информацию более дружелюбно;
2. Используйте метод IFormatter.ToString() для более гибкой настройки, и если добавить интерфейсы IFormatProvider и ICustomFormatter, будет разумнее настроить вывод сообщения.

6. Разница между значением и типом отсылки

1. Типы значений не поддерживают полиморфизм, который подходит для хранения данных, управляемых приложениями, тогда как ссылки поддерживают полиморфизм, который подходит для определения поведения приложений.
2. Для массивов, определяемых как типы значений, производительность программы может быть значительно повышена;
3. Тип значения имеет меньшую фрагментацию памяти кучи, мусор памяти и время косвенного доступа, а его возврат в методе осуществляется в виде репликации, чтобы избежать раскрытия внутренней структуры внешнему миру.
4. Типы значений используются в следующих сценариях: обязанности типов в основном используются для хранения данных; Публичные интерфейсы полностью определяются некоторыми атрибутами доступа к участникам данных; Подклассов никогда не бывает; Полиморфного поведения никогда не бывает.

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

1. Сделать наш код проще в написании и обслуживании;
2. Три стратегии инициализации констант: в конструкции; растительный метод; Постройте изменяемый вспомогательный класс (например, StringBuilder).

8. Убедиться, что 0 соответствует действительному статусу

1. Стандартное состояние типа значения должно быть 0;
2. 0 типа enum не должен быть недействительным; В атрибуте FlagsAttribute нужно гарантировать, что значение 0 является действительным состоянием;
3. Когда строка пуста, можно вернуть строку. пустая строка для пустой.

9. Множественные отношения равного суждения

1. ReferenceEquals() определяет, что ссылки равны, и она должна быть истинной, когда оба относятся к одному объекту.
2. Метод статического Equals() используется для сначала эталонного суждения, а затем для оценки типа значения;
3. Для оценки типа ссылки можно использовать метод переписывания Equals() при использовании семантики значений.
4. При переписке метода Equals() также следует переписать метод GetHashCode(), а операция operater==() должна быть выполнена одновременно.

10. Понять недостатки метода GetHashCode()

1. GetHashCode() применяется только к хеш-значениям ключей, определённых на основе хеша **, таких как HashTable или Dictionary;
2. GetHashCode() должен следовать трем соответствующим правилам: два равных объекта должны возвращать один и тот же хеш-код; должно быть инвариантом экземпляра; Хеш-функция должна производить случайное распределение по всем целым числам.

11. Придать приоритет использованию операторов foreach loop

1. Foreach может устранить проверку компилятором границы массива цикла For;
2. Круговая переменная foreach является только для чтения, и существует явное преобразование, которое создаёт исключение, если тип объекта объекта ** неверен;
3. Для использования foreach требуется **: наличие публичного метода GetEnumberator(); Интерфейс IEnumberable реализован явно. Реализован интерфейс IEnumerator;
4. Foreach может принести преимущества управления ресурсами, потому что если компилятор может определить интерфейс IDisposable, он может использовать оптимизированный try... наконец заблокировать;

12. Инициализация поля по умолчанию лучше, чем оператор присвоения

1. Срок жизни поля по умолчанию инициализирует тип значения в 0, а тип ссылки — в null.
2. Многократная инициализация одного и того же объекта снижает эффективность выполнения кода.
3. Инициализация поля в конструкторе способствует обработке исключений.

13. Используйте статический конструктор для инициализации статических элементов

1. Статический конструктор будет выполнен до доступа к любому методу, переменной или атрибуту класса;
2. Статические поля также будут выполняться перед статическим конструктором, и статический конструктор способствует обработке исключений.

14. Используйте цепочку конструкторов (в. NET 4.0 уже решает эту проблему с помощью дополнительных параметров)

1. Используйте это, чтобы передать работу инициализации другому конструктору и использовать базу для вызова конструктора базового класса;
2. Последовательность операций экземпляров типов: установить все статические поля в 0; Выполнение статических инициализаторов поля; статический конструктор, выполняющий базовый класс; Статические конструкторы, выполняющие текущий тип;
Установить все поля экземпляра в 0; Выполнить инициализаторы экземпляров полей; Выполните соответствующий конструктор экземпляра базового класса; Выполните конструктор экземпляра текущего типа.

15. Используйте операторы using и try/finally для очистки ресурсов

В методе Dispose() интерфейса IDisposable можно использовать GC.SuppressFinalize() для уведомления сборщика мусора, что финальная операция больше не выполняется.

16. Минимизировать мусор памяти

1. Выделение и уничтожение объектов на куче требует дополнительного времени процессора;
2. Методы уменьшения количества присваиваемых объектов: часто используемые локальные переменные продвигаются в поля; Предоставляет класс, который хранит распространённые экземпляры объектов Singleton, выражающих определённые типы.
3. Используйте StringBuilder для выполнения сложных операций со строками.

17. Минимизировать упаковку и распаковку

1. Обратите внимание на неявное преобразование типа в System.Object, и тип значения не должен заменяться на тип System.Object;
2. Использование интерфейсов вместо типов позволяет избежать коробки, то есть реализации типов значений из интерфейсов и вызова членов через интерфейсы.

18. Реализовать стандартный режим утилизации

1. Чтобы использовать ресурсы, не связанные с памятью, должен быть финализатор: мусорный сборщик добавит реализованные объекты финализатора в очередь завершения после завершения объектов памяти, которые их не завершили, а затем мусорный сборщик запустит новый поток для запуска финалайзеров на этих объектах. Это позволяет избежать проблемы утечки памяти, вызванной неуправляемыми ресурсами памяти.
2. Использование метода IDisposable.Dispose() требует четырёх аспектов работы: освобождения всех неуправляемых ресурсов; Освободите все управляемые ресурсы; Установите статусный маркер, указывающий, выполнен ли Dispose(); Вызовите GC.SuppressFinalize(this), чтобы отменить операцию завершения объекта;
3. Добавить защищённый виртуальный метод Dispose() в тип, требующий полиморфизма, и производный класс освобождает свою задачу, переписывая этот метод.
4. В типе, требующем IDisoposable интерфейса, мы должны реализовать терминатор, даже если он не нужен.

19. Определить и реализовать интерфейсы над типами наследования

1. Несвязанные типы могут совместно реализовать общий интерфейс, и реализовать интерфейс проще, чем наследование;
2. Интерфейс относительно стабилен, он инкапсулирует набор функций в интерфейсе как другие типы контрактов реализации, в то время как базовый класс может расширяться со временем.

20. Различать реализацию интерфейса и переписывание виртуальных методов

1. При реализации интерфейса в базовом классе производный класс должен использовать new, чтобы скрыть использование метода базового класса;
2. Метод интерфейса базового класса может быть объявлен виртуальным и затем реализован в производном классе.

21. Используйте доверение для выражения обратного вызова

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

22. Использование событий для определения внешних интерфейсов

1. Это должно быть объявлено как обычное событие и позволить компилятору создавать методы add и renmove для нас.
2. Используйте контейнер System.ComponentModel.EventHandlerList для хранения каждого обработчика событий и скрывайте сложность всех событий, если тип содержит большое количество событий.

23. Избегайте возврата ссылок на внутренние объекты классов

1. Поскольку доступ к объекту типа значения создаёт копию объекта, атрибуты определения типа значения вовсе не изменят состояние внутри объекта типа;
2. Постоянные типы могут избежать изменения состояния объекта;
3. Определить интерфейс для ограничения доступа к подмножеству, чтобы минимизировать ущерб внутреннему состоянию объекта.
4. Определить обёрточный объект для ограничения доступа к другому объекту;
5. Когда код клиента меняет внутренние элементы данных, можно реализовать режим Наблюдателя, чтобы объект мог проверять или соответствовать изменениям.

24. Декларативное программирование лучше императивного

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

25. Реализовать типы максимально сериализируемыми

1. Тип не является элементом управления интерфейсом, окном или формой, и тип должен поддерживать сериализацию;
2. При добавлении десериализированного атрибута NonSerializedAttribute значение по умолчанию может быть загружено методом OnDeserialization(), реализующим IDeserializationCallback;
3. В контроле версий можно использовать интерфейс ISerializable для гибкого управления, предоставить конструктор сериализации для инициализации объектов в зависимости от данных в потоке, а также требовать разрешения исключений SerializationFormatter при реализации.
4. Если нужно создать производный класс, необходимо предоставить метод крючка для производного класса.

26. Используйте интерфейсы IComparable и IComparer для реализации сортировочных отношений

1. Интерфейс IComparable используется для реализации наиболее естественной сортировки для типов, перегружая четыре оператора сравнения и предоставляя перегруженную версию метода CompareTo() для принятия определённых типов в качестве параметров.
2. IComparer используется для предоставления сортировочных отношений, отличающихся от IComparable, или для предоставления сортировочных отношений, которые сам тип утверждает, что не реализованы.

27. Избегайте ICloneing интерфейсов

1. Для типов значений нет необходимости поддерживать ICloneable интерфейс, просто используйте операцию присвоения по умолчанию;
2. Для базовых классов, которым может потребоваться поддержка ICloneable интерфейсов, следует создать защищённый конструктор репликации и избегать IConeable интерфейсов.

28. Избегать операторов принудительного преобразования

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

29. Рассматривайте использование нового модификатора только тогда, когда накопление новых версий вызывает проблемы

30. Максимально реализовать совместимые с CLS сборки
1. Для создания совместимой сборки необходимо соблюдать два правила: параметры и типы возвратных значений, используемые всеми публичными и защищёнными членами сборки, должны быть совместимы с CLS; Любой публичный и защищённый член, несовместимый с CLS, должен иметь совместимую с CLS альтернативу;
2. Вы можете обойти проверку типа совместимости CLS, явно реализовав интерфейс, и CLSCompliantAttribute не будет проверять совместимость частных членов с CLS.

31. Реализуйте максимально короткий и лаконичный метод

1. JIT-компилятор компилирует в единицах методов, и методы, которые не вызываются, не будут компилированы JIT;
2. Если код оператора Case в более длинном Switch заменять на один метод за раз, сэкономленное JIT-компилятором время будет умножаться;
3. Короткие и лаконичные методы и выбор меньшего количества локальных переменных позволяют обеспечить оптимальное использование регистров;
4. Чем меньше управляющих ветвей в методе, тем легче JIT-компилятору вводить переменные в регистры.

32. Реализовать небольшой размер и максимальную целостность

1. Поместить все публичные классы и классы общих баз в некоторые ассембли, поместить классы инструментов, обеспечивающие функции для публичных классов, в одну ассемблер, упаковать соответствующие публичные интерфейсы в отдельные ассембли и, наконец, обработать классы, расположенные по всей горизонтальной позиции приложения;
2. В принципе следует создавать два типа компонентов: один — это небольшая и агрегированная сборка с определённой функцией, а другая — большая и широкая сборка с общими функциями.

33. Ограничить видимость типов

1. Использование интерфейсов для экспозиции функций типов может облегчить создание внутренних классов без ограничения их доступности вне ассемблера;
2. Чем меньше публичных типов, подверженных внешнему миру, тем больше у вас вариантов для будущего расширения и изменений.

34. Создать крупно-гранулированный веб-API

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

35. Перезапись лучше, чем процессоры событий

1. Если процессор событий выдает исключение, другие процессоры цепочки событий не будут вызываться, но это не произойдёт с переписанным виртуальным методом.
2. Переписывание гораздо эффективнее, чем ассоциативные процессоры событий, которые требуют итерации по всему списку запросов, что занимает больше времени процессора.
3. На события можно реагировать во время выполнения с большей гибкостью, и несколько ответов могут быть связаны с одним и тем же событием.
4. Общее правило — работать с производным событием, и метод переписки лучше.

36. Добросовестное использование. Диагностика во время выполнения .NET

1. System.Diagnostics.Debug\Trace\EventLog предоставляет все необходимые инструменты для добавления диагностической информации в среду выполнения, и приложение может записывать в журнал системных событий, когда EventLog предоставляет ингредиент;
2. Наконец, не пишите свою собственную диагностическую библиотеку, у .NET FCL уже есть необходимая нам базовая библиотека.

37. Используйте стандартные механизмы конфигурации

1、. Класс System.Windows.Application фреймворка .NET определяет свойства для установления общего пути конфигурации;
2. Application.LocalAppDataPath и Application.userDataPath генерируют имена путей для локального каталога данных и пользовательских данных;
3. Не записывайте данные в ProgramFiles и системные папки Windows, эти места требуют более высоких прав на безопасность, не ожидайте у пользователей права на запись.

38. Настройка и поддержка связывания данных

1. Два объекта — BindingMananger и CurrencyManager — реализуют передачу данных между управлением и источником данных;
2. Преимущества привязки данных: использование привязки данных гораздо проще, чем написание собственного кода; Его следует использовать для областей видимости, кроме текстовых элементов данных — другие свойства дисплея также могут быть ограничены; Для привязок данных WindowsOS Forms — возможность обрабатывать многократную синхронизацию управления источниками данных, связанных с проверкой;
3. Если объект не поддерживает необходимые атрибуты, вы можете поддержать привязку данных, заблокировав текущий объект и затем добавив нужный объект.

39. Использовать. Валидация .NET

1. В ASP.NET есть пять элементов для проверки валидности, и вы можете использовать CustomValidator для получения нового класса для добавления собственного аутентификатора.
2. Для написания обработчика событий требуется подпроверка System.Windows.Forms.Control.

40. Выберите подходящий ** в соответствии с потребностями

1. Массив имеет два очевидных недостатка: его нельзя динамически изменять размер; Изменение размера занимает много времени;
2. ArrayList сочетает характеристики одномерных массивов и связанных списков, Queue и Stack — это специальные массивы, основанные на Array;
3. Когда программа становится более гибкой в добавлении и удалении элементов, она может создавать более надёжные типы, а при создании класса, имитирующего **, должна реализовать индексаторы и интерфейсы IEnumerable для него.

41. DataSet лучше, чем пользовательская структура

1. У DataSets есть два недостатка: взаимодействие между DataSets с использованием механизма сериализации XML и non-.NET кодом не очень хорошее; DataSet — это очень универсальный контейнер;
2. Сильные типы наборов данных нарушают больше правил проектирования, и их эффективность разработки значительно выше, чем у более элегантных дизайнов, написанных самими собой.

42. Используйте характеристики для упрощения отражения

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

43. Избегайте чрезмерного использования рефлексов

1. Параметры и значения возврата, используемые участниками Invoke, — это System.Object, который преобразует типы во время выполнения, но вероятность возникновения проблем стала более вероятной.
2. Интерфейс позволяет получить более чёткую и поддерживаемую систему, а отражение — очень мощный механизм позднего связывания. .NET фреймворк использует его для реализации привязки данных для управления Windows и веб-управления.

44. Создать специальные классы исключений для приложения

1. Единственная причина, по которой нужны разные классы исключений, — это возможность легко использовать разные подходы к разным ошибкам при написании процессоров catch;
2. Когда поведение восстановления могут отличаться, следует создавать различные классы исключений, предоставляя все конструкторы, поддерживаемые базовым классом исключений, мы можем создать полностью функциональный класс исключений для приложения и использовать атрибут InnerException для сохранения всей информации об ошибках, генерируемой низкоуровневыми условиями ошибки.

45. Отдавать приоритет ненормальным гарантиям безопасности

1. Сильная гарантия исключений обеспечивает лучший баланс между восстановлением из исключения и упрощённой обработкой исключений, при этом состояние программы остаётся неизменным при прерывании операции из-за этого исключения.
2. Сделать защитное копирование данных, подлежащих изменению, изменить защитную копию этих данных, операция посередине может вызвать исключение, и временная копия с оригинальным объектом будут обменяны;
3. Терминаторы, методы Dispose() и целевые методы, связанные с делегатами, должны гарантировать, что при каких обстоятельствах не допускают исключений.

46. Минимизировать совместимость

1. Существует три затраты на совместимость: стоимость перечисления данных между управляемыми и неуправляемыми кучами, стоимость переключения между управляемым и неуправляемым кодом, а также работа разработчиков, работающих с гибридными средами;
2. Использование типа blitable в interop позволяет эффективно репликацией между управляемыми и неуправляемыми средами без влияния внутренней структуры объекта.
3. Используйте функцию In/Out для обеспечения наиболее подходящих ненужных множественных репликаций и улучшите производительность, объявляя способ перечисления данных.
4. Использовать COM Interop для реализации совместимости с компонентами COM простым способом, использовать P/Invoke для вызова API Win32 или использовать коммутатор /CLR компилятора C++ для смешивания управляемого и неуправляемого кода;

47. Отдайте приоритет нормам безопасности

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

48. Освойте соответствующие инструменты и ресурсы

1. Использовать NUnit для установления автоматических модульных тестов (интегрированных в VS2010);
2. Инструмент FXCop получит код IL в ассемблере, проанализирует его с учетом разнородных правил кодирования и лучших практик и, наконец, сообщит о нарушении.
3. ILDasm — это инструмент для разборки IL, который помогает нам получить представление о деталях;
4. Shared Source CLI — это исходный код реализации, содержащий ядро .NET Framework и компилятор C#.




Предыдущий:Service Fabric — концепция состоятельного сервиса
Следующий:.net/c# SynchronizationContext для подробностей
Отказ:
Всё программное обеспечение, программные материалы или статьи, публикуемые Code Farmer Network, предназначены исключительно для учебных и исследовательских целей; Вышеуказанный контент не должен использоваться в коммерческих или незаконных целях, иначе пользователи несут все последствия. Информация на этом сайте взята из Интернета, и споры по авторским правам не имеют отношения к этому сайту. Вы должны полностью удалить вышеуказанный контент с компьютера в течение 24 часов после загрузки. Если вам нравится программа, пожалуйста, поддержите подлинное программное обеспечение, купите регистрацию и получите лучшие подлинные услуги. Если есть нарушение, пожалуйста, свяжитесь с нами по электронной почте.

Mail To:help@itsvse.com