Правила оформления текстов программ

Материал из Fabius NET DEV
Версия от 16:45, 6 марта 2020; Hisava (обсуждение | вклад)

(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Содержание

Помните! Код чаще читается, чем пишется, поэтому не экономьте на понятности и чистоте кода ради скорости набора.

Имена системных и прикладных классов, интерфейсов, методов, переменных, полей, свойств и.т.д. пишем по-русски, везде, где это возможно.

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

ОБЯЗАТЕЛЬНО комментировать ВСЕ Классы, Свойства и Методы по стандартам XML документации C#.

О том как это делать - http://club.shelek.ru/viewart.php?id=164

  • /// <summary>
  • /// это метод получения чего-то
  • /// </summary>
  • /// <param name="ЧтоТо">Этот параметр передается для чего-то</param>
  • /// <returns>Всегда возвращает Hello!</returns>
  • public string getSmth(string ЧтоТо)
  • {
  • return "hello";
  • }

Этот комментарий вставляется автоматом при нажатии 3 раза «/» - /// на строчке перед классом, методом и. т. п. Обязательно используемые теги, при наличии параметров и возвращаемых значений — <Summary>, <param name>, <returns> Полный список тегов и правила оформления — здесь: http://habrahabr.ru/post/41514/

Необходимо придерживаться *Соглашения по оформлению кода команды RSDN* первоисточник: http://rsdn.ru/article/mag/200401/codestyle.XML

Введение

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


Список терминов

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

operator – оператор (например, +, -, *, !) statement – инструкция (например, «a = b;», «if (a) {}») expression – выражение (например, «a – b + c», «a == 1»)

Именование идентификаторов

Общие правила
  • Помните! Код чаще читается, чем пишется, поэтому не экономьте на понятности и чистоте кода ради скорости набора.
  • Не используйте малопонятные префиксы или суффиксы (например, венгерскую нотацию), современные языки и средства разработки позволяют контролировать типы данных на этапе разработки и сборки.
  • Не используйте подчеркивание для отделения слов внутри идентификаторов, это удлиняет идентификаторы и затрудняет чтение. Вместо этого используйте стиль именования Кемел или Паскаль.
  • Старайтесь не использовать сокращения лишний раз, помните о тех, кто читает код.
  • Старайтесь делать имена идентификаторов как можно короче (но не в ущерб читабельности). Помните, что современные языки позволяют формировать имя из пространств имен и типов. Главное, чтобы смысл идентификатора был понятен в используемом контексте. Например, количество элементов коллекции лучше назвать Count, а не CountOfElementsInMyCollection.
  • Когда придумываете название для нового, общедоступного (public) класса, пространства имен или интерфейса, старайтесь не использовать имена, потенциально или явно конфликтующие со стандартными идентификаторами.
  • Предпочтительно использовать имена, которые ясно и четко описывают предназначение и/или смысл сущности.
  • Старайтесь не использовать для разных сущностей имена, отличающиеся только регистром букв. Разрабатываемые вами компоненты могут быть использованы из языков, не различающих регистр, и некоторые методы (или даже весь компонент) окажутся недоступными.
  • Старайтесь использовать имена с простым написанием. Их легче читать и набирать. Избегайте (в разумных пределах) использования слов с двойными буквами, сложным чередованием согласных. Прежде, чем остановиться в выборе имени, убедитесь, что оно легко пишется и однозначно воспринимается на слух. Если оно с трудом читается, и вы ошибаетесь при его наборе, возможно, стоит выбрать другое.
Стили использования регистра букв
  • Паскаль – указание этого стиля оформления идентификатора обозначает, что первая буква заглавная и все последующие первые буквы слов тоже заглавные. Например, BackColor, LastModified, DateTime.
  • Кэмел – указание этого стиля обозначает, что первая буква строчная, а остальные первые буквы слов заглавные. Например, borderColor, accessTime, templateName.
Сокращения
  • Не используйте аббревиатуры или неполные слова в идентификаторах, если только они не являются общепринятыми. Например, пишите GetWindow, а не GetWin.
  • Не используйте акронимы, если они не общеприняты в области информационных технологий.
  • Широко распространенные акронимы используйте для замены длинных фраз. Например, UI вместо User Interface или Olap вместо On-line Analytical Processing.
  • Если имеется идентификатор длиной менее трех букв, являющийся сокращением, то его записывают заглавными буквами, например System.IO, System.Web.UI. Имена длиннее двух букв записывайте в стиле Паскаль или Кэмел, например Guid, Xml, xmlDocument.

Примеры:

using System.IO; using System.Web.UI;

public class Math > { public const PI = ...; > public const E = ...; > }

Выбор слов
  • Не используйте имена, совпадающие с глобальными пространствами имен, такими, как System и Microsoft. Старайтесь по возможности избегать совпадения с названиями других сущностей .NET Framework.
  • Ниже приводится список имен, использование которых нежелательно:

AddHandler AddressOf Alias And Ansi As Assembly Auto Base Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType Date Decimal Declare Default Delegate Dim Do Double Each Else ElseIf End Enum Erase Error Event Exit ExternalSource False Finalize Finally Float For Friend Function Get GetType Goto Handles If Implements Imports In Inherits Integer Interface Is Let Lib Like Long Loop Me Mod Module MustInherit MustOverride MyBase MyClass Namespace New Next Not Nothing NotInheritable NotOverridable Object On Option Optional Or Overloads Overridable Overrides ParamArray Preserve Private Property Protected Public RaiseEvent ReadOnly ReDim Region REM RemoveHandler Resume Return Select Set Shadows Shared Short Single Static Step Stop String Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until volatile When While With WithEvents WriteOnly Xor eval extends instanceof package var

Пространства имен
  • Для пространства имен используйте имя компании, затем название продукта и, возможно, название подсистемы или существенной части проекта. Например, Rsdn.Framework, Rsdn.MegaTool.Scanner.
  • Используйте стиль Паскаль для регистра букв.
  • При объявлении пространства имен используйте единственную директиву namespace с полным именем пространства имен. Не используйте вложенные объявления пространств имен. Это замечание не относится к С++/MС++, так как в них нет отличной от вложенных пространств имен возможности создавать составные пространства имен.
  • Множественное число следует использовать в случае, если пространство имен объединяет некоторое количество разных, но семантически похожих сущностей. И наоборот, когда пространство имен содержит некую подсистему, стоит использовать единственное число. Сравните: Rsdn.Collections, но не Rsdn.Collection; Rsdn.Controls, но не Rsdn.Control; Rsdn.Network, но не Rsdn.Networks; Rsdn.Web, но не Rsdn.Webs;
  • Не используйте одно и то же имя для класса и пространства имен. Например, не используйте класс Debug и пространство имен Debug.

Примеры:

namespace Rsdn.Controls {} namespace Rsdn.Collections {} namespace Rsdn.Common {} namespace Rsdn.Network {}

Импорт пространств имен (директива using)
  • Перечислять импортируемые пространства имен необходимо в следующей последовательности: пространства имен .NET Framework, пространства имен сторонних производителей, собственные пространства имен из других проектов, пространства имен из текущего проекта. Каждый такой раздел должен отделяться одной пустой строкой, а имена внутри раздела должны быть отсортированы по алфавиту.
  • Директивы using, содержащие alias, должны идти в конце соответствующих разделов, и также быть упорядоченными по алфавиту.
Типы
  • Все не вложенные типы (размещаемые в пространствах имен или непосредственно в глобальном пространстве), за исключением делегатов, должны находиться в отдельных файлах.
  • Старайтесь объявлять вложенные типы в начале внешнего типа.
  • Старайтесь не делать излишней вложенности типов. Помните, что вложенными должны быть только тесно связанные типы.
Элементы типов (type members)
  • Элементы типов должны отделяться одной строкой друг от друга. Вложенные типы должны отделяться двумя строками. При объявлении большого количества полей, используемых внутри класса (не публичных), можно опускать пустую строку (особенно если поля отделены XML-комментариями).
Классы/Структуры
  • Используйте существительное (одно или несколько прилагательных и существительное) для имени класса.
  • Используйте стиль Паскаль для регистра букв.
  • Не используйте специальных префиксов, поясняющих, что это класс. Например, FileStream, а не CFileStream.
  • В подходящих случаях используйте составные слова для производных классов, где вторая часть слова поясняет базовый класс. К примеру, ApplicationException – вполне подходящее название для класса, унаследованного от Exception, поскольку ApplicationException является наследником класса Exception. Не стоит, однако злоупотреблять этим методом, пользуйтесь им разумно. К примеру, Button – вполне подходящее название для класса, производного от Control. Общее правило может быть, например, таким: «Если производный класс незначительно меняет свойства, поведение или внешний вид базового, используйте составные слова. Если класс значительно расширяет или меняет поведение базового, используйте новое существительное, отражающее суть производного класса». LinkLabel незначительно меняет внешний вид и поведение Label и, соответственно, использует составное имя.
  • Используйте составное имя, когда класс принадлежит некоторой специфичной категории, например FileStream, StringCollection, IntegrityException. Это относится к классам, которые являются потоками (Stream), коллекциями (Collection, Queue, Stack), ассоциативными контейнерами (Dictionary), исключениями (Exception).
  • Для классов-наследников, реализующих интерфейс IDictionary рекомендуется использовать тройное имя в виде <ТипКлюча>To<ТипЗначения>Dictionary. Вместо Dictionary можно использовать слово Map. Если это очевидно, можно опускать название значения. Примеры: StringToStringDictionary, StringToIntegerMap или KeywordMap. Переменным такого типа рекомендуется давать более конкретное семантическое название, например userToPasswordMap (user --> password), nameServiceDictionary (name --> service).
  • Для базового класса, предназначенного не для прямого использования, а для наследования, следует использовать суффикс Base. Например, CollectionBase. Такие классы также стоит делать абстрактными.
  • Коллекциям (реализующим интерфейс ICollection/IList) нужно давать имя в виде <ИмяЭлемента>Collection. Переменным же этих типов лучше давать имена, являющиеся множественным числом от элемента. Например, коллекция кнопок должна иметь имя ButtonCollection, а переменная buttons.

Примеры:

public class FileStream {} public class Button {} public class String {} public class StringCollection {}

Интерфейсы
  • Используйте описывающее существительное, прилагательное или одно или несколько прилагательных и существительное для идентификатора интерфейса. Например, IComponent – это описывающее существительное, ICustomAttributeProvider – это конкретизированное прилагательными существительное, а IPersistable – это характеризующее прилагательное.
  • Используйте стиль Паскаль для регистра букв.
  • Используйте префикс I (заглавная i) для интерфейсов, чтобы уточнить, что тип является интерфейсом. Старайтесь избегать интерфейсов с двумя I в начале, например IIdentifiable. Попробуйте подобрать синоним, например IRecognizable.
  • Для пары класс-интерфейс, в которой класс является некоторой стандартной или эталонной реализацией интерфейса, используйте одинаковые имена, отличающиеся только префиксом I для интерфейса. Например, IConfigurationManager и ConfigurationManager.
Атрибуты
  • Класс, являющийся атрибутом, должен иметь суффикс Attribute. Ни один класс, атрибутом не являющийся, не должен иметь такого суффикса. Если семантика класса требует в названии слова что-то вроде Attribute, используйте синонимы, например Descriptor, Sign, Qualifier, Specifier, Declarator.

Пример:

public class ObsoleteAttribute {};

Перечисления
  • Используйте стиль Паскаль для регистра букв в названии и значениях перечисления.
  • Не используйте суффикс Enum в названии типа, вместо этого используйте более конкретный суффикс, например Style, Type, Mode, State. Чтобы код легче читался, используйте следующее правило: «Название перечисления + is + значение должно образовывать простое предложение». Например: BorderStyle.Single ( Border style is single, ThreadState.Aborted --> Thread state is “aborted”.
  • Если перечисление обладает атрибутом [Flags], используйте множественное число или суффикс Flags.
  • Записывайте значения перечисления на отдельных строках. Если элементы имеют определенный семантический порядок, описывайте их именно так, иначе используйте алфавитный порядок.
  • Если значение одного из членов перечисления зависит от других, используйте булевы операции (&, |, ^), а не литеральные константы.
  • Имена членов перечисления не должны содержать имени перечисления и другой не относящейся к конкретному значению информации.


Пример:

public enum CodeStyle {

 Good,
 Normal,
 Bad,
 Ugly

}

Поля
  • Непубличные поля (private, protected и protected internal) именуются в стиле Кэмел и начинаются с префикса _.
  • Публичные поля именуются в соответствии с правилами именования свойств.
  • Одна декларация должна содержать не более одного поля и должна располагаться на одной строке.

class A {

   // Так нельзя:
   int _var1, _var2; 
   // Так тоже:
   int _var1, 
       _var2; 
   // Надо так:
   int _var1;
   int _var2;
   ...
  • Публичные поля должны в обязательном порядке документироваться XML-комментариями. Желательно снабжать XML-комментариями и непубличные поля.
  • Обращаясь к публичным полям старайтесь избегать их передачи по ссылке, т.к. велика вероятность того, что в следующих версиях приложения эти поля могут стать свойствами.
Методы
  • Используйте глаголы или комбинацию глагола и существительных и прилагательных для имен методов.
  • Используйте стиль Паскаль для регистра букв (вне зависимости от области видимости метода).

Примеры:

private int RemoveAll() {} public void GetCharArray() {} internal static Invoke() {}

Свойства
  • Используйте существительное или одно или несколько прилагательных и существительное для имени свойства.
  • Используйте стиль Паскаль для регистра букв.
  • В подходящих случаях используйте имя свойства, совпадающее с типом его значения. Одним из критериев для применения этого правила является наличие единственного свойства со значением некоторого (нетривиального) типа.
  • Старайтесь избегать использования имен свойств, совпадающих с названиями каких-либо типов, если значения этих свойств не являются значениями этих типов. В этом случае будет трудно получить доступ к статическим членам типа или значениям перечисления. Например, при использовании конструкции public int Color { get; set; }, обращение Color.Xxx будет рассматриваться как получение свойства Color и затем доступ к свойствам или методам этого значения, которое в данном случае будет являться типа System.Int32.
  • Рассмотрите возможность включения имени типа в идентификатор свойства, особенно если этот тип – перечисление. Например, OuterBorderStyle, BackColor, SocketFlags.

Примеры:

public class SampleClass
{
   public Color BackColor 
   {
       // Code for Get and Set accessors goes here.
   }
}
public class Control 
{
   public Color Color 
   { 
       get {/* Insert code here. */} 
       set {/* Insert code here. */} 
   }
}
События
  • Используйте суффикс EventHandler для делегатов, являющихся типами событий. Другие классы не должны использовать этот суффикс.
  • Создавая событие в компонентах и control-ах, старайтесь описывать их по следующей схеме. Определите два параметра с именами sender и e. Параметр sender описывает объект, инициировавший событие, и всегда должен быть типа object, даже если возможно использование более конкретного типа. Второй параметр, e, должен содержать состояние и дополнительную информацию, соответствующую событию. Этот параметр должен быть конкретного типа, относящегося к событию.
  • Делайте тип, описывающий связанную с событием информацию, производным от EventArgs, и используйте суффикс EventArgs. Другие классы, не описывающие информацию о событии, не должны использовать этот суффикс.
  • Для имен событий старайтесь использовать глаголы, которые описывают производимое над объектом действие (например, Click, GotFocus или FontChanged).
  • Не используйте суффиксы наподобие On, Before, After для идентификатора события. Используйте соответствующую форму глагола, например Closing перед закрытием и Closed после закрытия.
  • При описании события также предоставляйте виртуальный protected-метод, который можно переопределить в классе-наследнике. Называйте такой метод OnXxx, где Xxx – имя события. В качестве параметров таких методов не следует передавать sender, так как – это всегда текущий объект (this).
  • Пытайтесь подобрать стандартный делегат и название для своих событий. Например, если ваш элемент управления должен реагировать на нажатие кнопки мыши, следует использовать стандартное событие Click. Для элементов управления, обычно, такие события уже объявлены в базовом классе Control.
Параметры
  • Из имени и типа параметра должны быть понятны его назначение и смысл.
  • Используйте стиль Кэмел для регистра букв в имени параметра.
  • Старайтесь избегать указания типа в имени параметра.
  • Не усложняйте прототип метода «зарезервированными» параметрами, которые, возможно, будут использоваться в будущих версиях реализации. Если в будущем понадобится новый параметр, используйте перегрузку методов.
  • Имена параметров не должны совпадать с именами членов класса. Если этого все же не удается избежать, используйте ключевое слово this для разрешения конфликтов (допустимо различие в регистре или префиксе _ для полей классов).

Стиль кода

Оформление
  • Используйте табуляцию, а не пробелы для отступов. В средах типа VS лучше использовать режим табуляции. Его можно настроить в диалоге Options -> Text Editor -> Ваш_любимый_язык ->Tabs: Indenting = Smart, Tabs = Keep Tabs. В общем, это настройки по умолчанию для многих языков.
  • При форматировании текста (кроме отступа в начале строки) используйте пробелы. Для этого удобно использовать режим Virtual Space, который в VS 2002 настраивается в Options -> Text Editor -> Ваш_любимый_язык -> General.
  • Избегайте строк длиннее 78 символов, переносите инструкцию на другую строку при необходимости.
  • При переносе части кода инструкций и описаний на другую строку вторая и последующая строки должны быть отбиты вправо на один отступ (табуляцию).
  • Оставляйте запятую на предыдущей строке так же, как вы это делаете в обычных языках (русском, например).
  • Избегайте лишних скобок, обрамляющих выражения целиком. Лишние скобки усложняют восприятие кода и увеличивают возможность ошибки. Если вы не уверены в приоритете операторов, лучше загляните в соответствующий раздел документации.
  • Не размещайте несколько инструкций на одной строке. Каждая инструкция должна начинаться с новой строки.
Локальные переменные
  • Используйте стиль Кэмел для регистра букв в именах переменных.
  • Объявляйте переменные непосредственно перед их использованием.
  • Счетчики в циклах традиционно называют i, j, k, l, m, n.
  • Для временных локальных переменных, используемых в коротких участках кода, можно давать имена, состоящие из начальных букв слов имени типа.
  • Не объявляйте более одной переменной в одной инструкции.
  • Имена скрытых (protected, protected internal и private) переменных-членов класса и статических переменных начинайте с одиночного символа подчеркивания.
  • Имена публичных (internal и public) переменных должны быть в стиле Паскаль и не иметь подчеркивания в качестве префикса.
  • Комментируйте объявления так, чтобы были понятны назначение и способы использования переменной.
  • Инициализируйте переменные при объявлении, если это возможно.
Комментарии
  • Не используйте многострочные (/*...*/) комментарии для описания классов и методов, используйте для этих целей XML documentation-комментарии. Многострочные комментарии не могут быть вложенными, поэтому их использование может создать проблемы.
  • Для описания сути некоторого участка кода, пояснений к алгоритму и другой важной информации используйте несколько подряд идущих однострочных комментариев (//...). Между группой комментариев и собственно кодом поставьте пустую строку. Это покажет, что комментарий относится к блоку кода, а не к конкретной инструкции. Напротив, если комментарий относится к конкретной инструкции, прижмите его вплотную к этой инструкции.
  • Комментируйте объявления переменных, по возможности используя XML-комментарии. Если язык не поддерживает XML-комментариев, можно использовать однострочные комментарии на той же строке, как это показано ниже.
  • Отделяйте текст комментария одним пробелом «// Текст комментария.».
  • Комментируя код, старайтесь объяснять, что он делает, а не какая операция производится. Так, инструкции if соответствует выражение «если... то...», причем часть, идущая за «то», является кодом, который будет выполняться, если выражение в if будет верным. Таким образом, для конструкции «if (somePath && File.Exists(somePath))», нужно написать комментарий «// Если выбранный файл существует, то...», а не «// Производим проверку на наличие файла и, если он имеется, удаляем его». Часть предложения, идущую за «то», вписывайте непосредственно перед выполнением конкретных действий. Для инструкций, осуществляющих действия, пишите «// Производим...» или «// Делаем...», где вместо троеточия вписывайте описания действий. Описывая действия, старайтесь описывать суть происходящего, а не то, что делают те или иные операторы. Так, совершенно бессмысленны комментарии вроде «Присваиваем переменной a значение b» или «вызываем метод f».
  • Помните, что экономить на комментариях нельзя. Однако не стоит также формально подходить к процессу создания комментариев. Задача комментария – упростить понимание кода. Есть немало случаев, когда сам код отличным образом себя документирует.
Объявления и определения

Объявления классов и интерфейсов

  • Базовые классы и интерфейсы должны указываться на той же строке, что и объявление класса. Если список не умещается в 78 символов, снесите его, начиная с двоеточия, и сделайте отступ на одну табуляцию вправо. Размещайте на строке столько элементов, сколько умещается в 78 символов.
  • Открывающая фигурная скобка должна находиться на строке, следующей за объявлением класса, на том же уровне отступа, что и класс.
  • Закрывающая фигурная скобка должна находиться на отдельной строке на том же уровне, что и класс.
  • Содержимое класса должно быть сдвинуто на одну табуляцию относительно объявления.

Объявления членов класса и интерфейса

  • Между именем метода и открывающей скобкой списка параметров не должно быть пробела.
  • Тело метода должно быть сдвинуто на одну табуляцию относительно объявления.
  • Вид доступа к члену класса всегда должен быть явно указан.
  • Модификаторы должны идти в следующем порядке: сначала модификаторы доступа, а потом все остальные.
  • В конструкторе вызов конструктора базового (или этого же) класса (конструкция «: base(...)» «: this(...)») оформляется таким же образом, как список базовых типов у класса.
Инструкции (statements)
  • Каждая инструкция должна располагаться на отдельной строке.
  • Составные инструкции оформляются открывающей фигурной скобкой на отдельной строке, списком инструкций, сдвинутым на одну табуляцию, и закрывающей фигурной скобкой на отдельной строке.
  • После ключевого слова (напр. if, while, for) перед открывающей круглой скобкой (если она есть) должен быть пробел.
Общие правила разработки классов
  • Допускается определять в классе публичные (public и internal) поля, но они должны однозначно интерпретироваться как lightweight-поля. Оформляйте их стилем Паскаль и указывайте в документации, что не следует передавать такие поля по ссылке. Старайтесь (если, конечно, на то нет особых причин) избегать смешивания в одном классе/структуре публичных полей и свойств.
  • Старайтесь реализовать в виде свойств только то, что отражает состояние класса или объекта. Например, если вы делаете свою коллекцию, то количество элементов (Count) должно быть свойством, а операцию преобразования ее в массив (GetArray) лучше сделать методом. Причем вместо Get в данном случае лучше использовать другое слово, например, ToXxxx. То есть метод будет называться ToArray().
  • Используйте методы, если выполняемая операция является преобразованием, имеет побочный эффект или долго выполняется.
  • Используйте метод, если важен порядок выполнения операций.
  • Свойство не должно менять своего значения от вызова к вызову, если состояние объекта не изменяется. Если результат при новом вызове может быть другим при том же состоянии объекта, используйте метод.
  • Не используйте свойства «только для записи». Потребность в таком свойстве может быть признаком плохого проектирования.
  • Запечатанные (sealed) классы не должны иметь ни защищенных, ни виртуальных методов. Такие методы используются в производных классах, а sealed-класс не может быть базовым.
  • Классы, реализующие интерфейс IDisposable, ни в коем случае не должны передаваться по значению.
  • Классы, определяющие только статические методы и свойства, не должны иметь открытых или защищенных конструкторов, поскольку никогда не нужно создавать их экземпляры.
  • Не используйте литеральные константы (магические числа, зашитые в код размеры буферов, времена ожидания и тому подобное). Лучше определите константу (если вы никогда не будете ее менять) или переменную только для чтения (если она может измениться в будущих версиях вашего класса).
  • Старайтесь обрабатывать только известные вам исключения. Если вы все же обрабатываете все исключения, то или, проведя необходимую обработку, генерируйте исключение повторно, чтобы его могли обработать последующие фильтры, или выводите пользователю максимально полную информацию об ошибке. Если целью перехвата исключений является очистка ресурсов после сбоя, лучше воспользоваться секцией finally.
Оформляйте смысловые блоки код в регионы, для повышения удобочитаемости, особенно внутри класса

например:

public abstract class ЭлементДаннныхСправочника: INotifyPropertyChanged 
{
#region События интерфейса INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged; 
#endregion
#region Свойства и поля
private int ид;
public int ИД {get; set;}
private string код;
public string Код {get;set;}
#endregion
#region Конструктор и методы класса 
protected abstract void ПроверитьПравильностьОбъекта();
public ЭлементДаннныхСправочника() {}
#endregion 
}

Смотрите также

Заглавная страница