Есть ли хорошее использование частичных классов вне сценариев кода, созданного веб-формами / winforms? Или эта функция в основном поддерживает это?
Частичные классы в C #
Ответы (20)
Частично он предназначен для поддержки сценариев (WebForms, WinForms, LINQ-to-SQL и т. Д.), Смешивающих сгенерированный код с кодом программиста.
Есть больше причин использовать его. Например, если у вас есть большие классы в больших, громоздких файлах, но классы имеют группы логически связанных методов, частичные классы могут быть вариантом, чтобы сделать размеры ваших файлов более управляемыми.
Генерация кода была движущей силой частичных классов. Необходимость возникает из-за наличия генерируемого кодом класса, который постоянно меняется, но позволяет разработчикам предоставлять собственный код как часть класса, который не будет переопределяться каждый раз, когда вносятся изменения, заставляющие регенерировать класс.
Возьмем, к примеру, WinForms или Typed-DataSets (или любого дизайнера в этом отношении). Каждый раз, когда вы вносите изменения в конструктор, он сериализует соответствующий код в файл. Допустим, вам нужно предоставить несколько дополнительных методов, о которых генератор ничего не знает. Если вы добавите его в сгенерированный файл, ваши изменения будут потеряны при его следующем создании.
В проекте, над которым я сейчас работаю, используется генерация кода для всех DAL, BLL и бизнес-сущностей. Однако генератор получает только 75% информации. Оставшаяся часть должна быть закодирована вручную (например, пользовательская бизнес-логика). Я могу предположить, что каждый класс BLL имеет метод SelectAll, поэтому его легко сгенерировать. Однако мой клиент BLL также должен иметь метод SelectAllByLocation. Я не могу поместить это в свой генератор, потому что он не является общим для всех классов BLL. Поэтому я генерирую все свои классы как частичные классы, а затем в отдельном файле определяю свои собственные методы. Теперь, когда моя структура изменится или мне по какой-то причине понадобится регенерировать мой BLL, мой собственный код не будет уничтожен.
Я использую частичные классы как средство разделения различных подэлементов настраиваемых элементов управления, которые я пишу. Кроме того, при использовании с программным обеспечением для создания сущностей он позволяет таким продуктам, как LLBLGen, создавать сгенерированные версии классов, а также настраиваемые версии, редактируемые пользователем, которые не будут заменены, если сущности необходимо регенерировать.
Я часто использую частичные классы, чтобы дать каждому вложенному классу отдельный файл. Я работал над некоторыми архитектурами, в которых большая часть реализации требовалась только для одного класса, поэтому мы вложили эти классы в этот один класс. Было разумно упростить обслуживание файлов, используя возможность частичного класса и разбивая каждый на отдельный файл.
Мы также использовали их для группирования стандартных настроек или скрытия набора свойств. Такие вещи. Это удобный способ внесения изменений в акции (просто скопируйте файл и измените имя частичного класса на целевой класс - если, конечно, целевой класс тоже будет частичным).
Другим возможным использованием частичных классов было бы использование преимуществ частичных методов для выборочного исчезновения методов с использованием условной компиляции - это было бы здорово для диагностического кода в режиме отладки или специализированных сценариев модульного тестирования.
Вы можете объявить частичный метод как абстрактный метод, а затем в другом частичном классе, когда вы вводите ключевое слово «partial», вы можете воспользоваться преимуществами Intellisense для создания реализации этого метода.
Если вы окружите одну часть операторами условной сборки, то вы можете легко отключить код, предназначенный только для отладки или тестирования. В приведенном ниже примере в режиме DEBUG вызывается метод LogSomethingDebugOnly, но в сборке релиза это похоже на то, что метод вообще не существует - хороший способ держать диагностический код подальше от производственного кода без множества ветвлений или несколько блоков условной компиляции.
// Main Part
public partial class Class1
{
private partial void LogSomethingDebugOnly();
public void SomeMethod()
{
LogSomethingDebugOnly();
// do the real work
}
}
// Debug Part - probably in a different file
public partial class Class1
{
#if DEBUG
private partial void LogSomethingDebugOnly()
{
// Do the logging or diagnostic work
}
#endif
}
// Main Part
или достаточно просто поместить метод в // Debug Part
?
- person surfmuggle; 29.10.2012
LINQ to SQL эффективно использует частичные классы для расширения кода, созданного конструктором. Я думаю, вы обычно найдете этот образец частичных классов, используемых дизайнерским кодом.
Я считаю, что частичные классы очень полезны. Обычно они используются для расширения автоматически сгенерированных классов. Я использовал их в одном проекте с тяжелыми юнит-тестами. Мои классы UT имели сложные зависимости, и было не очень практично разделять код между несколькими классами. Конечно, лучше использовать наследование \ композицию, но в некоторых случаях частичные классы могут быть полезны.
Как упоминалось ранее, я тоже считаю, что это запах кода.
Если класс настолько велик, что его нужно разделить на несколько файлов, это означает, что он нарушает принцип единой ответственности и выполняет слишком много вещей. Большой класс можно разбить на более мелкие, которые взаимодействуют друг с другом.
Если вам нужно использовать частичные классы или регионы для организации кода, подумайте, должны ли они быть в своих собственных классах. Это увеличивает удобочитаемость, и вы получаете больше повторного использования кода.
может быть, уже слишком поздно, но позвольте мне добавить и мои 2 цента:
*. При работе над большими проектами распространение класса на отдельные файлы позволяет нескольким программистам работать над ним одновременно.
*. Вы можете легко написать свой код (для расширенной функциональности) для класса, созданного VS.NET. Это позволит вам написать код по своему усмотрению, не вмешиваясь в код, сгенерированный системой.
Там, где я нахожусь, у нас есть программа, которая обрабатывает входящие файлы от клиентов. Он настроен так, что код каждого клиента находится в своем собственном проекте библиотеки классов, который знает, как обрабатывать любой формат, который клиент выбирает для использования.
Основной код использует библиотеки, определяя довольно обширный интерфейс, который должен реализовать класс в библиотеке (вероятно, должно быть несколько отдельных интерфейсов, но сейчас уже слишком поздно). Иногда для этого требуется гораздо больше кода в том же классе, чем мы обычно думаем. Частичные занятия позволяют несколько их разбить.
В относительно сложных элементах управления UserControl я помещаю элементы обработки событий в один файл, а рисунок и свойства - в другой. Частичные классы отлично подходят для этого. Обычно эти части класса относительно независимы, и приятно иметь возможность редактировать рисование и обработку событий бок о бок.
Пару лет назад я работал над проектом, в котором у нас был типизированный класс DataSet, в котором было много кода: методы в DataTables, методы в TableAdapters, объявления экземпляров TableAdapter и т. Д. Это была главная центральная точка проекта, над которой всем приходилось часто работать, и было много споров в системе контроля версий по поводу файла кода частичного класса.
Поэтому я разделил файл кода на исправления или шесть файлов частичного класса, сгруппированных по функциям, чтобы мы могли работать с более мелкими частями и не блокировать весь файл каждый раз, когда нам нужно было что-то изменить.
(Конечно, мы могли бы решить эту проблему, не используя систему управления исходным кодом с исключительной блокировкой, но это уже другая проблема.)
В общем, я считаю это запахом кода.
Если ваш класс настолько сложен, то его, вероятно, можно разбить на более мелкие повторно используемые компоненты.
Или это означает, что нет иерархии наследования там, где она должна быть.
Для сценариев генерации кода это хорошо, но я думаю, что генерация кода - это еще один запах кода.
Я опаздываю в игре ... но только мои 2 цента ...
Одним из вариантов использования может быть рефакторинг существующего класса бога в существующей базе унаследованного кода до нескольких частичных классов. Это могло бы улучшить обнаруживаемость кода - если соблюдается надлежащее соглашение об именах для имен файлов, содержащих частичные классы. Это также могло бы уменьшить репозиторий исходного кода - до некоторой степени разрешить и объединить.
В идеале класс бога следует разбить на несколько небольших классов, каждый из которых несет единственную ответственность. Иногда выполнение средних и крупных рефакторингов мешает работе. В таких случаях частичные классы могут дать временное облегчение.
Коррекция, как указал Мэтт, обе стороны детали должны быть в одной сборке. моя вина.
Я использую его на уровне доступа к данным. Сгенерированные классы, такие как преобразователь, запрашивают партиал. Если мне нужно добавить метод сопоставления, например, чтобы выполнить причудливую нагрузку, которая не сгенерирована, я добавляю его в настраиваемый класс.
В конце концов, программист, использующий уровень данных на бизнес-уровне, видит только один класс со всей необходимой ему функциональностью. И если источник данных изменяется, общие части могут быть легко сгенерированы без перезаписи пользовательского материала.
Я только что нашел применение частичным классам. У меня есть класс [DataContract], который я использую для передачи данных клиенту. Я хотел, чтобы клиент мог отображать класс определенным образом (вывод текста). поэтому я создал частичный класс и переопределил метод ToString.
Иногда вы можете встретить в работе ужасно старый код, из-за которого рефакторинг на отдельные элементы без нарушения существующего кода становится практически невозможным.
Когда у вас нет возможности или времени для создания более подлинной архитектуры, частичные классы позволяют невероятно легко разделить логику там, где это необходимо. Это позволяет существующему коду продолжать использовать ту же архитектуру, в то время как вы становитесь на шаг ближе к более конкретной архитектуре.
Везде, где вы раньше использовали #region
разделы, вероятно, имеет больше смысла как отдельные файлы в частичных классах.
Я лично использую частичные классы для больших классов, где статические члены входят в один файл, а члены экземпляра - в другой.
РЕДАКТИРОВАТЬ: Инструменты DSL для Visual Studio используют частичные классы.
Таким образом, это функция, которую использует многие автоматически сгенерированные коды. Вместо использования #region автоматически сгенерированный код переходит в один файл, а пользовательский код (также называемый настраиваемым кодом) переходит в другой и даже в разные каталоги, чтобы разработчик не запутался с таким количеством бессмысленных файлов.
Хорошо иметь этот выбор, который вы можете комбинировать - но не принудительно использовать - с наследованием
Также может быть удобно разделить логику некоторых классов по нескольким каталогам. Конечно, для компьютеров это то же самое, но это улучшает удобочитаемость для пользователя.