Нейминг

  1. Следуйте правилам нейминга, используйте семантику
  2. Не использовать сокращения
  3. Использовать адекватные термины для нейминга
  4. Познакомиться с кодстайлом, префиксами для интерфейсов

Do:

  1. Следуйте кодстайлу
  2. Следуйте правилам нейминга комитов (https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716)
  3. Использовать конструкторы для создания полностью инициализированого объекта
  4. Минимизировать область доступа к данным, закрывать возможность изменять тип из-вне. Стремиться к минимизации статических полей. Если поле класса используется только внутри одного метода - инлайнить, если используется для передачи данных между методами - перепроектировать решение.
  5. Проверяйте может ли метод выполниться с переданными аргументами, если эти аргументы - это пользовательский ввод.
  6. При реализации методов создания или поиска, стоит возвращать сущности, а не какие-то их части - названия или идентификаторы. Если написано, что нужно найти магазин, то ожидается, что вернется не строка, а магазин.
  7. Минимизировать использование статических методов, полей и классов. Если в коде была использована статика, то нужно оозначить комментарием почему это решение лучше в таком виде, нежели без статики.
  8. Стараться минимизировать вложенность за счет инвертирования условий.
  9. Делать всю возможную валидацию аргументов в конструкторе (например, на null)
  10. Стараться делать типы иммутабельными. Особенно в кейсах, где мутабельность объекта нужно для инициализации вне конструктора:
csharp
    var group = new Group();
    group.Name = "Tasks";

  1. Поддерживать инвариант типа. Никакое изменение не должно делать экземпляр класса не валидным.
  2. Разделять бизнес логику и логику работы с UI. Разделять логику, парсинг аргументов и валидацию
  3. Если есть зависимость от внешних сущностей, то их нужно прокидывать аргументами.
  4. Бросать понятные ошибки бизнес логики (т.е. не из namespace'a System). Обрабатывать возможные NRE, OutOfRange etc и вместо них бросать понятные. Сообщения ошибок стоит писать на английском. Если хочется поддержать русский, то нужно смотреть в сторону локализации.
  5. Старайтесь вместо множества вложенных операторов выделить все граничные условия и обработать их в самом начале метода для достижения большей читаемости кода. см.

https://refactoring.guru/ru/replace-nested-conditional-with-guard-clauses 16. Использовать статические Compiled Regular Expressions вместо Interpreted

https://learn.microsoft.com/en-us/dotnet/standard/base-types/best-practices 17. Используйте свойства/автосвойства вместо геттер/сеттер методов.

Don’t

  1. Не вносить изменения в конфиги CI и анализаторов без апрува преподавателей.
  2. Не используйте в коде магические числа. Имеет смысл выносить как константное поле, чтобы по его названию можно было понять, что это.
  3. Работать с потоками ввода-вывода в бизнес-логике
  4. Ловить и игнорировать исключение, которое не может быть обработано
  5. Не используйте default или специализированные (-1, int.MaxValue и т.д.) значения как определение того, что значение не найдено. Если метод может не найти результат, то метод нужно называть Find и он должен вернуть null в случае ссылочных типов. Для примитивов стоит использовать Nullable. Для коллекций стоит возвращать пустой список или массив, если ничего не нашлось, а не null.
  6. Избегайте кастов там, где можно их не использовать. Программа должна стремиться к повышению типизации и увеличении количества мест, где происходят проверки во время компиляции.
  7. Минимизировать количество даун кастов. Стараться не использовать более общие типы в сигнатурах, если они не поддерживаются.
  8. Не использовать Tuple, ValueTuple и KVP в сигнатурах своих типов или методов
  9. Не оставлять код, который не нужен\не используется, не комментировать очевидные места
  10. Не использовать наследование для переиспользования логики. Если объект наследуется, то справедливым должно быть высказывание, что производный объект является базовым (см. LSP).
  11. Не используйте циклы для перебора коллекций ради того чтобы в теле цикла вернуть/найти объект или собрать лист значений. Воспользуйтесь LINQ, а именно: .SelectMany(), .Where(), FirstOrDefault()
  12. Не использовать Reflection для доступа к private полям/методам.
  13. Не использовать boolean флаги для того чтобы управлять условиями выхода из цикла.
  14. Не использовать SQL-like синтаксис для написания LINQ.
  15. Не использовать конструкции вида
.ToList().ForEach(...)

/ .ToList().Select(...)для итерации по колекциям.

Suggestions

  1. Использовать LINQ для работы с коллекциями вместо написания большого количества foreach.
  2. Используйте подход Arrange-Act-Assert при написании ваших тест-кейсов. https://docs.microsoft.com/ru-ru/visualstudio/test/unit-test-basics?view=vs-2019#write-your-tests
  3. Использовать в тестах специализированные проверки вместо общих, по типу Assert.Contains(…) вместо Assert.True(collection.Contains(…)).
  4. При использовании регулярных выражений рекомендуется помимо валидации также производить и парсинг с помощью Named capture group’ов.

https://www.regular-expressions.info/named.html 5. Рекомендуется создавать Exception’ы на каждый scope отдельно (StudentException, GroupException…), а уже в них держать приватный конструктор и статические методы для создания исключений на каждую конкретную ситуацию