Вопрос

Существуют ли эффективные способы использования частичных классов вне сценариев сгенерированного кода webforms / winforms?Или эта функция в основном предназначена для поддержки этого?

Это было полезно?

Решение

Частично это делается для поддержки сценариев (WebForms, WinForms, LINQ-to-SQL и т.д.), смешивающих сгенерированный код с кодом программиста.

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

Другие советы

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

Возьмем, к примеру, WinForms или Typed-DataSets (или любой дизайнер, если уж на то пошло).Каждый раз, когда вы вносите изменения в конструктор, он сериализует соответствующий код в файл.Допустим, вам нужно предоставить несколько дополнительных методов, о которых генератор ничего не знает.Если вы добавите его в сгенерированный файл, ваши изменения будут потеряны при следующем его создании.

Проект, над которым я сейчас работаю, использует генерацию кода для всех DAL, BLL и бизнес-объектов.Однако генератор получает от нас только 75% информации.Оставшаяся часть должна быть закодирована вручную (например, пользовательская бизнес-логика).Я могу предположить, что у каждого класса BLL есть метод selectAll, так что его легко сгенерировать.Однако у моего клиента BLL также должен быть метод SelectAllByLocation.Я не могу поместить это в свой генератор, потому что оно не является универсальным для всех классов BLL.Поэтому я генерирую все свои классы как частичные классы, а затем в отдельном файле определяю свои пользовательские методы.Теперь, в будущем, когда моя структура изменится или мне по какой-то причине понадобится восстановить мой BLL, мой пользовательский код не будет уничтожен.

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

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

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

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

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

Если вы окружите одну часть операторами условной сборки, то вы можете легко отключить код, предназначенный только для отладки или тестирования.В приведенном ниже примере в режиме ОТЛАДКИ вызывается метод 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
}

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

Я нахожу частичные занятия чрезвычайно полезными.Обычно они используются для расширения автоматически сгенерированных классов.Я использовал их в одном проекте с тяжелыми модульными тестами.Мои классы UT имели сложные зависимости, и было не очень практично разделять код по нескольким классам.Конечно, лучше использовать наследование \ композицию, но в некоторых случаях частичные классы могут быть полезны для объединения.

Как упоминалось ранее, я тоже думаю, что это запах кода.

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

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

может быть, уже слишком поздно, но, пожалуйста, позвольте мне тоже добавить свои 2 цента:

*. При работе над большими проектами распространение класса по отдельным файлам позволяет нескольким программистам работать над ним одновременно.

*. Вы можете легко написать свой код (для расширения функциональности) для VS.NET созданного класса.Это позволит вам написать код по своему усмотрению, не вмешиваясь в системный код, сгенерированный системой

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

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

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

Пару лет назад я работал над проектом, где у нас был типизированный класс DataSet, содержащий тонну кода:Методы в таблицах данных, методы в адаптерах таблиц, объявления экземпляров TableAdapter - называйте как хотите.Это был важный центральный пункт проекта, над которым всем приходилось часто работать, и было много споров в системе управления версиями по поводу файла кода частичного класса.

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

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

Как правило, я считаю, что это запах кода.

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

Или это означает, что нет иерархии наследования там, где она должна быть.

Для сценариев генерации кода это хорошо, но я думаю, что генерация кода - это еще один запах кода.

Я опаздываю в игре...но только мои 2 цента...

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

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

Поправка, как указал Мэтт, обе стороны детали должны быть в одной сборке.я виноват.

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

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

Я только что нашел применение для частичных классов.У меня есть класс [DataContract], который я использую для передачи данных клиенту.Я хотел, чтобы клиент мог отображать класс определенным образом (вывод текста).поэтому я создал частичный класс и переопределил метод toString .

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

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

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

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

Редактировать:DSL Tools для Visual Studio использует частичные классы.

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

Хорошо, что у вас есть такой выбор, который вы можете комбинировать - но не заставлять использовать - с наследованием

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top