Частичные классы C#, плохо разрабатывают? [закрытый]

Я задаюсь вопросом, почему 'частичный класс' понятие даже существует в C#/VB.NET. Я работаю над приложением, и мы читаем (на самом деле очень хорошую) книгу, относящуюся к платформе разработки, которую мы реализуем на работе. В книге автор обеспечивает большую кодовую базу / обертка вокруг платформы API и объясняет, как он разработал его, поскольку он преподает различные темы разработке платформы.

Так или иначе длинная короткая история - он использует частичные классы, повсеместно, как способ фальсифицировать множественное наследование в C# (IMO). То, почему он только не разделял классы на несколько и использовал состав, вне меня. У него будет 3 'частичных класса' файлами для составления его базового класса, каждый w/3-500 строк кода... И несколько раз делает это в его API.

Вы находите это допустимым? Если бы это был я, я следовал бы за S.R.P. и создал бы несколько классов для обработки различных необходимых поведений, то созданный базовый класс, который имеет экземпляры этих классов как участники (например, состав). Почему MS даже помещал частичный класс в платформу? Они удалили способность расшириться/свернуть весь код на каждом уровне объема в C# (это было позволено в C++), потому что это, очевидно, просто позволяло дурные привычки - частичный класс, IMO, то же самое. Я предполагаю, что мой вопрос: можно ли объяснить мне, когда была бы законная причина когда-нибудь для использования частичного класса?

Править: Я знаю что для Web/WinForms нет никакого другого выбора. Но за пределами этого? Почему MS только не помещал некоторое другое ключевое слово для того, чтобы склеить классы кода-genn'ed? Или есть ли действительно законный сценарий дизайна, который заслуживает его?

Я не означаю это быть напыщенной речью / военный поток. Я честно надеюсь изучать что-то здесь. Когда частичные классы должны использоваться в дизайне кода? Простой вопрос, никакая потребность закрыться

Спасибо

68
задан 76484 26 June 2016 в 06:04
поделиться

12 ответов

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

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

Тем не менее, вполне возможно иметь слишком много хорошего. Несколько советов:

  • Не делайте свои классы частичными ради того, чтобы они были частичными .

  • Не размещайте частичные классы где-либо, кроме одного другого. Если вам нужно перейти к совершенно не относящемуся к делу разделу проекта, чтобы увидеть вторую половину класса, вы, вероятно, делаете это неправильно.

  • Не используйте partial как метод скрытия размера класса. Если вы разбиваете свои классы с помощью partial , потому что они слишком велики, вам следует вернуться к Принципу единой ответственности .

  • Если у вас есть три или более частичных фрагментов для одного и того же класса, это почти гарантия того, что вы злоупотребляете частичным. Два - это типичная верхняя граница разумности, и она обычно используется для сегментации автоматически сгенерированного кода из рукописного кода.

Короче говоря, он повсюду использует частичные классы как способ имитации множественного наследования в C # (IMO).Почему он просто не разделил классы на несколько и не использовал композицию, мне непонятно. У него будет 3 файла «частичного класса», чтобы составить его базовый класс, каждый с 3-500 строками кода ... И делает это несколько раз в своем API.

Да, это определенно явное злоупотребление частичным !

97
ответ дан 24 November 2019 в 14:12
поделиться

Еще одно хорошее применение частичных классов - реализация абстрактного фабричного шаблона . Сделайте корневой объект фабрики частичным, а затем поместите фактические фабричные методы в тот же файл, что и класс, инстанцируемый фабрикой.

РЕДАКТИРОВАТЬ: Частичные классы также хорошо работают для классов, которые взаимодействуют с файлом конфигурации. Поместите код, содержащий параметры конфигурации, рядом с кодом, который фактически использует параметр конфигурации.

2
ответ дан 24 November 2019 в 14:12
поделиться

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

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

Пример ASP.NET:

  • Page.aspx
  • Page.aspx.cs <- Ваш код
  • Page.aspx.Designer.cs <- Частичный класс, содержащий автоматически сгенерированный код.

Пример WinForms:

  • Form1.resx
  • Form1.cs <- Ваш код
  • Form1.Designer.cs <- Частичный класс, содержащий автоматически сгенерированный код
2
ответ дан 24 November 2019 в 14:12
поделиться

Я дважды использовал частичный класс в VB.Net, и оба раза в тех редких случаях, когда мне требовалось позднее связывание. Просто создайте частичный класс и выключите Option Strict Off вверху.

1
ответ дан 24 November 2019 в 14:12
поделиться

Еще одно законное использование частичных классов - помочь уменьшить «монолитную сеть». служебный "беспорядок в WCF. Вы хотите разбить его на логические группы функциональных возможностей, но не хотите создавать множество отдельных экземпляров службы / конечных точек (предположительно, потому что они совместно используют состояние, ресурсы и т. Д.).

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

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

11
ответ дан 24 November 2019 в 14:12
поделиться

Есть две причины, по которым я буду (и буду) использовать частичные классы.

  1. Для разделения автоматически сгенерированных частей кода (например, кода конструктора WinForms или вывода T4).
  2. Разрешить вложенным типам их собственный файл, в то же время обеспечивая инкапсуляцию, требуемую вашим проектом.

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

Для более подробного обсуждения ознакомьтесь с вопросом, который дублирует этот: Частичные классы в C #

12
ответ дан 24 November 2019 в 14:12
поделиться

Я использовал частичные классы для «физического» отделения статических методов доступа к данным от свойств и методов бизнес-класса в активной архитектуре записи. Например, у нас параллельно были частичные классы Company и CompanyData. Преимущество состояло в том, что один файл был POCO, а другой содержал только методы доступа к данным. Это было ступенькой к прекращению доступа к данным в классах репозитория в устаревшем приложении. Я думаю, что это было законное использование, оно определенно сделало процесс рефакторинга более разумным.

2
ответ дан 24 November 2019 в 14:12
поделиться

Я полностью согласен с ответом Джона . Но я бы пошел еще дальше.

  • Не делайте свои классы частичными.

Единственное использование частичных классов, которое я считаю «хорошим дизайном», - это автоматически сгенерированный код. Любое другое использование почти наверняка приведет к ненужному разделению вашего класса. (На самом деле, я вижу, что второй пункт Джеффа о вложенных классах, возможно, является допустимым)

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

2
ответ дан 24 November 2019 в 14:12
поделиться

Частичный класс существует в платформе .Net исключительно для того, чтобы дизайнеры Visual Studio (например, дизайнер Asp.Net и дизайнер Windows Forms) могли генерировать код / ​​беспорядок с вашими классами, сохраняя этот сгенерированный код в отдельный файл.

(См. Частичные классы .NET против наследования )

Если вы сделаете что-то подобное (сгенерируете код, который должен сосуществовать с кодом, написанным пользователем), то вы также можете найти частичные классы полезными, но Я не верю, что Microsoft когда-либо предполагала, что частичные классы как языковая концепция будут полезны кому-либо, кроме команды Visual Studio.

Дело не в том, что использование частичных классов - плохой дизайн - просто вы, вероятно, не найдете им применения.

1
ответ дан 24 November 2019 в 14:12
поделиться

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

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

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

7
ответ дан 24 November 2019 в 14:12
поделиться

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

1
ответ дан 24 November 2019 в 14:12
поделиться

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

Однако у меня есть ситуация, в которой частичные классы кажутся очень полезными: Я создаю серию приложений, которые в конечном итоге будут объединены в пакет. Все они будут иметь главную форму, которая будет обеспечивать некоторую функциональность, и несколько общих компонентов (например, форму для отображения отчетов). Хотя я мог бы определить базовый класс и наследоваться от него, это означало бы много переделок, когда придет время объединить все приложения в "корпоративную" версию продукта.

Таким образом, частичные классы весьма полезны, поскольку я могу довольно просто включить различные частичные классы в объединенную версию, при этом сохраняя возможность создания отдельных, автономных версий продукта. Если бы я попытался сделать это с помощью наследования, то в итоге каждый компонент вызывал бы свою собственную версию общих компонентов (например, InvoiceReportViewer, PurchasingReportsViewer и т.д.), а не просто вызывал бы ReportsViewer и знал бы, что Visual Studio интегрирует все биты за меня.

1
ответ дан 24 November 2019 в 14:12
поделиться