Когда целесообразно использовать частичные классы С#?

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

Ответ 1

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

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

Ответ 2

Другим вариантом использования является разделение реализации различных интерфейсов, например:

partial class MyClass : IF1, IF2, IF3
{
    // main implementation of MyClass
}


partial class MyClass
{
    // implementation of IF1
}

partial class MyClass
{
    // implementation of IF2
}

Ответ 3

Помимо других ответов...

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

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

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

Ответ 4

  • Несколько разработчиков. Использование частичных классов. Несколько разработчиков могут работать в одном классе без труда.
  • Генератор кода Частичные классы в основном используются генератором кода для сохранения разные проблемы разделяют.
  • Частичные методы. Используя частичные классы, вы также можете определить Partial methods, где разработчик может просто определить метод, а другой разработчик может это реализовать.
  • Только декларация только частичного кода Даже код компилируется только с объявлением метода, и если реализация метода нет, компилятор может безопасно удалить этот фрагмент кода и не будет ошибок времени компиляции.

    Чтобы проверить точку 4. Просто создайте проект winform и включите эту строку после Form1 Constructor и попытайтесь скомпилировать код

    partial void Ontest(string s);
    

Вот некоторые моменты, которые следует учитывать при реализации частичных классов: -

  • Используйте частичное ключевое слово в каждой части частичного класса.
  • Имя каждой части частичного класса должно быть одинаковым, но имя исходного файла для каждой части частичного класса может быть различным.
  • Все части частичного класса должны находиться в одном и том же пространстве имен.
  • Каждая часть частичного класса должна быть в одной сборке или DLL, другими словами, вы не можете создать частичный класс в исходных файлах из другого проекта библиотеки классов.
  • Каждая часть частичного класса должна иметь такую ​​же доступность. (т.е. частный, открытый или защищенный).
  • Если вы наследуете класс или интерфейс для частичного класса, он наследуется всеми частями этого частичного класса.
  • Если часть частичного класса запечатана, весь класс будет запечатан.
  • Если часть частичного класса является абстрактной, то весь класс будет считаться абстрактным классом.

Ответ 5

Одно большое использование - это разделение сгенерированного кода из рукописного кода, принадлежащего к одному классу.

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

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

Ответ 6

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

public partial class Product
{
    // 50 business logic embedded in methods and properties..
}

public partial class Product
{
    // another 50 business logic embedded in methods and properties..
}
//finally compile with product.class file.

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

Product1.cs

public partial class Product
{
    //you are writing the business logic for fast moving product
}

Product2.cs

public partial class Product
{
    // Another developer writing some business logic...
}

Надеюсь, что это имеет смысл!

Ответ 7

держите все как можно более чистым при работе с огромными классами или при работе в команде вы можете редактировать без переопределения (или всегда совершать изменения)

Ответ 8

Частичные классы охватывают несколько файлов.

How can you use the partial modifier on a C# class declaration?

С частичным вы можете физически отделить класс от нескольких файлов.

Это часто делают генераторы кода.

Пример

С обычными классами С# вы не можете объявить класс в двух отдельных файлах в одном проекте.

Но с помощью частичного модификатора вы можете.

Это полезно, если один файл обычно редактируется, а другой генерируется машиной или редко редактируется.

An Example will clear your concept.

class Program
{
    static void Main()
    {
    A.A1();
    A.A2();
    }
}

//Contents of file A1.cs: C#

using System;

partial class A
{
    public static void A1()
    {
    Console.WriteLine("A1");
    }
}

//Contents of file A2.cs: C#

using System;

partial class A
{
    public static void A2()
    {
    Console.WriteLine("A2");
    }
}

Output

A1
A2

Здесь требуется частичный.

If you remove the partial modifier, you will get an error containing this text: [The namespace '<global namespace>' already contains a definition for 'A'].

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

How does the C# compiler deal with partial classes?

Если вы разобрали вышеуказанную программу, вы увидите, что файлы A1.cs и A2.cs удалены.

Вы обнаружите, что класс A присутствует.

IL Disassembler Так: Класс A будет содержать методы A1 и A2 в том же кодовом блоке. Два класса были объединены в один.

Скомпилированный результат A1.cs и A2.cs: С#

internal class A
{
    // Methods
    public static void A1()
    {
    Console.WriteLine("A1");
    }

    public static void A2()
    {
    Console.WriteLine("A2");
    }
}

Резюме

Частичные классы могут упростить некоторые ситуации программирования на С#.

Они часто используются в Visual Studio при создании программ Windows Forms/WPF.

Сгенерированный машиной код С# является отдельным.

Или Вы можете найти здесь описание .

Ответ 9

Основное использование для частичных классов - сгенерированный код. Если вы посмотрите на сеть WPF (Windows Presentation Foundation), вы определяете свой пользовательский интерфейс с разметкой (XML). Эта разметка скомпилирована в частичные классы. Вы заполняете код частичными классами.

Ответ 10

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

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

MyProvider.cs - основная логика

MyProvider.Forum.cs - методы, относящиеся конкретно к форуму

MyProvider.Product.cs - методы для продуктов

Это просто еще один способ сохранить организованность.

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

Ответ 11

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

Вы можете "расширить" классы обслуживания, не перезаписывая их при обновлении служебной ссылки.

Ответ 12

Другое использование, которое я видел,

Расширение большого абстрактного класса в отношении логики доступа к данным,

У меня есть разные файлы с именами Post.cs, Comment.cs, Pages.cs...

in Post.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of post..
}


in Comment.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of comment..
}

in Pages.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of Pages..
}

Ответ 13

В качестве альтернативы директивам предварительного компилятора.

Если вы используете директивы предварительного компилятора (а именно #IF DEBUG), то вы получите некоторый gnarly выглядящий код, смешанный с вашим фактическим кодом Release.

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

Ответ 14

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

Partial Public Class zzFileConverterRegistrar
    Event Register(ByVal mainConverter as zzFileConverter)
    Sub registerAll(ByVal mainConverter as zzFileConverter)
        RaiseEvent Register(mainConverter)
    End Sub
End Class

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

Partial Public Class zzFileConverterRegistrar
    Private Sub RegisterGif(ByVal mainConverter as zzFileConverter) Handles Me.Register
        mainConverter.RegisterConverter("GIF", GifConverter.NewFactory))
    End Sub
End Class

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

Edit/Добавление Чтобы быть ясным, цель этого - предоставить средства, с помощью которых различные отдельные классы могут позволить основной программе или классу узнать о них. Единственное, что основной файловый конвертер будет делать с zzFileConverterRegistrar, это создать один экземпляр и вызвать метод registerAll, который будет запускать событие Register. Любой модуль, который хочет подключить это событие, может выполнить произвольный код в ответ на него (что вся идея), но нет ничего, что мог бы сделать модуль, ненадлежащим расширением класса zzFileConverterRegistrar, кроме определения метода, имя которого совпадает с чем-то другим, Было бы возможно, чтобы одно неправильно написанное расширение нарушило другое неправильно написанное расширение, но решение для этого предназначено для тех, кто не хочет, чтобы его расширение сломалось, чтобы просто написать его правильно.

Можно, без использования частичных классов, иметь немного кода где-то внутри основного класса конвертера файлов, который выглядел бы так:

  RegisterConverter("GIF", GifConvertor.NewFactory)
  RegisterConverter("BMP", BmpConvertor.NewFactory)
  RegisterConverter("JPEG", JpegConvertor.NewFactory)

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

Ответ 15

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

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

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

example -

  • MainClass.cs - содержит поля, конструктор и т.д.
  • MainClass1.cs - новый код разработчиков при их реализации
  • MainClass2.cs - это еще один класс разработчиков для их нового кода.

Ответ 16

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

Например, рассмотрим класс С# System.Math... этот класс. Я бы не пытался использовать 70+ методов в одном и том же файле кода. Было бы кошмаром поддерживать.

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

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

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

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

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

Ответ 17

Из MSDN:

1. Время компиляции, атрибуты определений частичного типа объединяются. Например, рассмотрите следующие объявления:

[SerializableAttribute]
partial class Moon { }

[ObsoleteAttribute]
partial class Moon { }

Они эквивалентны следующим объявлениям:

[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }

Ниже перечислены все определения частичного типа:

  • Комментарии XML

  • интерфейсы

  • атрибуты параметров универсального типа

  • атрибуты класса

  • Участники

2. Другое дело, вложенные частичные классы также могут быть частичными:

partial class ClassWithNestedClass
{
    partial class NestedClass { }
}

partial class ClassWithNestedClass
{
    partial class NestedClass { }
}

Ответ 18

Вот список некоторых преимуществ частичных классов.

Вы можете отделить код дизайна пользовательского интерфейса и код бизнес-логики, чтобы его было легко читать и понимать. Например, вы разрабатываете веб-приложение с помощью Visual Studio и добавляете новую веб-форму, тогда есть два исходных файла: "aspx.cs" и "aspx.designer.cs". Эти два файла имеют один и тот же класс с неполным ключевым словом. Класс .aspx.cs имеет код бизнес-логики, тогда как "aspx.designer.cs" имеет определение управления пользовательским интерфейсом.

При работе с автоматически сгенерированным источником код может быть добавлен в класс без необходимости воссоздавать исходный файл. Например, вы работаете с LINQ to SQL и создаете файл DBML. Теперь, когда вы перетаскиваете таблицу, он создает неполный класс в файле designer.cs, и все столбцы таблицы имеют свойства в классе. Вам нужно больше столбцов в этой таблице для привязки к сетке пользовательского интерфейса, но вы не хотите добавлять новый столбец в таблицу базы данных, чтобы вы могли создать отдельный исходный файл для этого класса, у которого есть новое свойство для этого столбца, и оно будет быть частичным классом. Таким образом, это влияет на сопоставление между таблицей базы данных и сущностью DBML, но вы можете легко получить дополнительное поле. Это означает, что вы можете написать код самостоятельно, не вникая в сгенерированный системой код.

Более одного разработчика могут одновременно записать код для класса.

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

Ответ 19

Всякий раз, когда у меня есть класс, который содержит вложенный класс, который имеет какой-либо значительный размер/сложность, я помещаю класс как partial и помещаю вложенный класс в отдельный файл. Я называю файл, содержащий вложенный класс, с помощью правила: [имя класса]. [Имя вложенного класса].cs.

В следующем блоге MSDN объясняется использование неполных классов с вложенными классами для удобства обслуживания: http://blogs.msdn.com/b/marcelolr/archive/2009/04/13/using-partial-classes-with-nested-classes-for-maintainability.aspx

Ответ 20

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

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

Например, OpenGL - это конечный автомат, есть куча методов, которые могут быть изменены во всем мире, однако, по моему опыту, связывая нечто похожее с OpenGL, где существует так много методов, класс может легко превышать 10 000 LOC.

Частичные классы сломают это для меня и помогут мне быстро найти методы.

Ответ 21

Частичные классы в основном используются для помощи генераторам кода, поэтому мы (пользователи) не теряем всю нашу работу/изменения в сгенерированные классы, такие как класс ASP.NET.designer.cs, каждый раз, когда мы регенерируем, почти все новые инструменты, которые генерируют код LINQ, EntityFrameworks, ASP.NET используют частичные классы для сгенерированного кода, поэтому мы можем безопасно добавлять или изменять логику этих сгенерированных кодов, используя преимущества классов и методов Partial, но будьте очень осторожны, прежде чем добавлять материал в сгенерированный код используя Partial classes, это проще, если мы сломаем сборку, но хуже, если мы представим ошибки времени выполнения. Подробнее см. http://www.4guysfromrolla.com/articles/071509-1.aspx

Ответ 23

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

Группировка предметов класса

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

public class MyClass{  
  //Member variables
  //Constructors
  //Properties
  //Methods
}

С частичными классами мы можем пойти дальше и разделить разделы на отдельные файлы. Как правило, команда может добавлять суффикс к каждому файлу с соответствующим ему разделом. Таким образом, в приведенном выше примере мы имеем что-то вроде: MyClassMembers.cs, MyClassConstructors.cs, MyClassProperties.cs, MyClassMethods.cs.

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

//Methods - See partial class

Управление областью использования операторов/пространства имен

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