Лучшие практики: когда нельзя/не использовать частичные классы

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

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

Что вы думаете? Есть ли проблема с использованием частичных классов, подобных этому, или это сводится к предпочтениям?

Например, у меня обычно что-то вроде этого:

  • MainClass.cs
  • MainClass.Helper1.cs
  • MainClass.Helper2.cs

...

// Inside of MainClass.cs I have code like this:

public abstract partial class MainClass
{
    // ...
}

// Then in the MainClass.Helper1.cs I have:

partial class MainClass
{
   private class Helper1
   {
       // ...
   }
}

person Wayne Bloss    schedule 08.12.2008    source источник


Ответы (10)


Частичные классы в первую очередь предназначены для использования генераторами кода, такими как дизайнеры, но я использую подход, который вы процитировали, в частности, когда объект реализует несколько (нетривиальных) интерфейсов, я считаю полезным разбить это до 1 файла на реализацию интерфейса. У меня также обычно есть файл для статических методов, которые обычно достаточно отличаются от методов экземпляра, чтобы гарантировать разделение.

person Marc Gravell    schedule 08.12.2008
comment
+1 за статические методы, мне кажется, это имеет смысл, если их много. - person SwissCoder; 10.05.2013

Лично я не вижу ничего плохого в использовании частичных классов, подобных этому, но это только мое личное мнение. Единственное, что может показаться «плохой практикой», — это называть ваши классы «Помощник1» и «Помощник2» (но это может быть примером только для пояснения).

Если вы используете подобные частичные классы, ознакомьтесь с (бесплатной) надстройкой vsCommands ( для Visual Studio 2008), что позволяет легко группировать файлы в обозревателе решений (точно так же, как файлы конструктора) без редактирования файла проекта.

person Patrik Svensson    schedule 08.12.2008
comment
Спасибо, искал такой плагин. Я обходился макросом, который я написал для этого. - person Wayne Bloss; 09.12.2008

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

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

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

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

person Zachary Yates    schedule 08.12.2008
comment
Вам никогда не нужны вспомогательные классы, правда? Меня это удивляет, потому что я вижу так много классов в самой структуре, у которых есть вспомогательные классы, такие как частные перечислители и частные списки (Dictionary..KeyCollection, Dictionary..ValueCollection и т. д.). - person Wayne Bloss; 09.12.2008
comment
Например... System.Enumerable имеет около 30 вспомогательных классов, вложенных в него. (ТРИДЦАТЬ!!) Так что, я думаю, вы бы сказали, что это, возможно, плохой дизайн? - person Wayne Bloss; 09.12.2008
comment
повторно сгенерировать файл без потери пользовательской работы, безусловно, лучшая причина для частичного класса, такая удобная, такая полезная - person ChrisHDog; 09.12.2008
comment
Ну, я не имею в виду, что вспомогательные классы — это плохой дизайн. Я не использую вспомогательные классы, если у меня есть основной класс. Я встраиваю вспомогательную функциональность в основной класс. Я использую вспомогательные классы, когда мне не принадлежит основной класс (например, фреймворк/сторонний класс). - person Zachary Yates; 09.12.2008

Я не очень большой поклонник частичных классов и сам их не использую.

Однако единственный раз, когда я нахожу их полезными и приемлемыми для использования, это когда вы хотите добавить что-то в код дизайнера LINQ to SQL, но помимо этого я обнаружил, что вы распространяете код в разные файлы только ради этого. , это может сделать его очень трудным для чтения и управления.

Может быть, если у вас есть классы, разбитые на множество файлов, возможно, ваши классы делают слишком много... просто мысль :)

person Nathan W    schedule 08.12.2008
comment
На самом деле мне легче управлять, если каждый класс имеет свой собственный файл... Таким образом, я могу открыть вложенный класс в одном окне, а родительский класс в другом окне и легче переключаться между ними. - person Wayne Bloss; 09.12.2008
comment
Кроме того, см. мой комментарий к ответу Эндрю ниже. Я думаю, что не вижу, какое отношение имеет размер к вложенному классу или нет... - person Wayne Bloss; 09.12.2008

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

Разделение — главная причина, по которой мне нравится это решение. Частный внутренний класс гораздо меньше связан со всем остальным, потому что никто другой не может его видеть или использовать (хотя они могут говорить о возможности доступа к закрытым данным родительского класса, что обычно было бы плохой идеей).

person Neil    schedule 09.12.2008

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

person Pitambar    schedule 28.12.2012

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

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

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

person Andrew Kennan    schedule 08.12.2008
comment
Я предполагаю, что я не вижу, какое отношение имеет размер к вложенности класса или нет. Вложенный класс не может использоваться другими классами, поэтому я вложил класс исключительно для достижения этой функциональности. Затем я помещаю его в собственный файл независимо от его размера, чтобы я мог редактировать вложенный класс отдельно. - person Wayne Bloss; 09.12.2008
comment
Отличная ссылка. И, может быть, даже убедительно. - person dkretz; 09.12.2008
comment
Я обычно использую внутренние классы для простого хранения данных. Я не сторонник разделяемых классов для чего-либо, кроме генераторов кода, потому что они снижают удобочитаемость кода, особенно если кто-то лениво помещает метод MainClass в файл MainClass.Helper1.cs. - person Andrew Kennan; 09.12.2008

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

Но! Хотя и не часто, я иногда обнаруживал, что широкое модульное тестирование класса (обычно внешних классов) приводит к гигантским классам модульного тестирования. Разделение класса модульного теста на частичные классы делает его немного проще для глаз и для понимания.

Подобно идее группировки при наследовании от нескольких интерфейсов, модульный тест может быть сгруппирован для функций.

person Choco Smith    schedule 18.09.2014

Я думаю, хорошо помнить, что поведение вашего инструмента по умолчанию заключается в создании низкоуровневой формы Coupling Not Cohesion; и относиться к нему скептически, и переопределять его, если это не имеет смысла по некоторым из конкретных причин, перечисленных выше. Но это нехорошее поведение по умолчанию.

person dkretz    schedule 09.12.2008

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

person Samnang    schedule 09.12.2008