Частичный член (справочник по C#)
Частичный член имеет одно объявление об объявлении и часто одно реализующее объявление. Объявление объявления не включает текст. Объявление реализации предоставляет текст элемента. Частичные члены позволяют конструкторам классов предоставлять перехватчики элементов, которые могут быть реализованы с помощью таких средств, как генераторы источников. Частичные типы и члены предоставляют разработчикам возможность писать часть типа, а средства записывают другие части типа. Если разработчик не предоставляет необязательное объявление реализации, компилятор может удалить объявление объявления во время компиляции. Следующие условия применяются к частичным элементам:
- Объявления должны начинаться с контекстного ключевого слова partial.
- Сигнатуры в обеих частях разделяемого типа должны совпадать.
Ключевое partial
слово не допускается для конструкторов, завершения, перегруженных операторов или объявлений событий. До C# 13 partial
не было разрешено для свойств или индексаторов.
Частичный метод не требуется для объявления реализации в следующих случаях:
- У него нет модификаторов специальных возможностей (включая стандартные
private
). - Он возвращает
void
. - У него нет
out
параметров. - У него нет ни одного из следующих модификаторов
virtual
,override
, ,sealed
илиnew
extern
.
Любой элемент, который не соответствует всем этим ограничениям (например, public virtual partial void
методу), должен предоставить реализацию. Частичные свойства и индексаторы должны иметь реализацию.
В следующем примере показан частичный метод, соответствующий предыдущим ограничениям:
partial class MyPartialClass
{
// Declaring definition
partial void OnSomethingHappened(string s);
}
// This part can be in a separate file.
partial class MyPartialClass
{
// Comment out this method and the program
// will still compile.
partial void OnSomethingHappened(string s) =>
Console.WriteLine($"Something happened: {s}");
}
Частичные члены также могут быть полезны в сочетании с генераторами источников. Например, можно определить регулярное выражение, используя следующий шаблон.
public partial class RegExSourceGenerator
{
[GeneratedRegex("cat|dog", RegexOptions.IgnoreCase, "en-US")]
private static partial Regex CatOrDogGeneratedRegex();
private static void EvaluateText(string text)
{
if (CatOrDogGeneratedRegex().IsMatch(text))
{
// Take action with matching text
}
}
}
В предыдущем примере показан частичный метод, который должен иметь объявление реализации. В рамках сборки генератор источника регулярных выражений создает объявление реализации.
В следующем примере показана декларативная объявление и реализация объявления для класса. Так как возвращаемый тип метода не void
является ( string
это) и его доступом public
является, метод должен иметь объявление реализации:
// Declaring declaration
public partial class PartialExamples
{
/// <summary>
/// Gets or sets the number of elements that the List can contain.
/// </summary>
public partial int Capacity { get; set; }
/// <summary>
/// Gets or sets the element at the specified index.
/// </summary>
/// <param name="index">The index</param>
/// <returns>The string stored at that index</returns>
public partial string this[int index] { get; set; }
public partial string? TryGetAt(int index);
}
public partial class PartialExamples
{
private List<string> _items = [
"one",
"two",
"three",
"four",
"five"
];
// Implementing declaration
/// <summary>
/// Gets or sets the number of elements that the List can contain.
/// </summary>
/// <remarks>
/// If the value is less than the current capacity, the list will shrink to the
/// new value. If the value is negative, the list isn't modified.
/// </remarks>
public partial int Capacity
{
get => _items.Count;
set
{
if ((value != _items.Count) && (value >= 0))
{
_items.Capacity = value;
}
}
}
public partial string this[int index]
{
get => _items[index];
set => _items[index] = value;
}
/// <summary>
/// Gets the element at the specified index.
/// </summary>
/// <param name="index">The index</param>
/// <returns>The string stored at that index, or null if out of bounds</returns>
public partial string? TryGetAt(int index)
{
if (index < _items.Count)
{
return _items[index];
}
return null;
}
}
В предыдущем примере показаны правила объединения двух объявлений:
- Совпадения подписей: в целом подписи для объявления и реализации объявлений должны соответствовать. Это включает модификатор специальных возможностей для методов, свойств, индексаторов и отдельных методов доступа. Он включает в себя тип параметров и модификаторы типа ссылок для всех параметров. Возвращаемый тип и любой модификатор типа ссылок должен соответствовать. Имена элементов кортежа должны совпадать. Однако некоторые правила являются гибкими:
- Декларируемые и реализующие объявления могут иметь разные параметры заметки, допускающие значение NULL. Это означает, что один из них может быть пустым и другим включенным значением NULL.
- Различия в доступности NULL, не связанные с забвительным значением NULL, создают предупреждение.
- Значения параметров по умолчанию не должны соответствовать. Компилятор выдает предупреждение, если реализация объявления метода или индексатора объявляет значение параметра по умолчанию.
- Компилятор выдает предупреждение, если имена параметров не совпадают. Создаваемый IL содержит имена параметров объявления.
- Комментарии к документации: комментарии к документации можно включить из любого объявления. Если декларативные и реализующие объявления включают комментарии к документации, будут включены комментарии из реализующего объявления. В предыдущем примере комментарии документации включают:
Capacity
Для свойства комментарии принимаются из объявления реализации. Примечания реализации объявлений используются, когда оба объявления имеют///
примечания.- Для индексатора комментарии принимаются из объявления объявления. В объявлении реализации нет
///
комментариев. - Для
TryGetAt
этого комментарии взяты из реализуемого объявления. Объявление объявления не содержит///
комментариев. - Созданный XML содержит комментарии документации для всех
public
участников.
- Большинство объявлений атрибутов объединяются. Однако все атрибуты сведений о вызывающем объекте определяются с
AllowMultiple=false
помощью . Компилятор распознает любой атрибут сведений о вызывающем объекте в объявлении. Все атрибуты сведений о вызывающем объекте в объявлении реализации игнорируются. Компилятор выдает предупреждение при добавлении атрибутов сведений о вызывающем объекте в объявление реализации.