An important innovation in C# 13.0 are partial properties and indexes. Many developers have been waiting for this language feature since the introduction of partial methods in C# 3.0. C# keywords partial
Even classes have been around since C# 2.0.
Advertisement
Dr. Holger Schweitenberg is the technical director of the expert network www.IT-Visions.de, which supports many medium-sized and large companies through consulting and training as well as software development with 53 renowned experts. Through his attendance at numerous national and international conferences as well as more than 90 expert books and more than 1,500 expert articles, Holger Schwittenberg is one of the best-known experts for .NET and web technologies in Germany.
With partial classes you can split program code of the same class into multiple code files – without using inheritance. This is not only useful for greater clarity in large classes, but it is mainly used when one part of the class is automatically generated and the other part of the class is written manually. This approach is used in .NET, for example, in GUI libraries such as ASP.NET WebForms and Blazor, in reverse engineering of databases with Entity Framework and Entity Framework Core, and in source generators (e.g. regular expression and for JSON serialization).
In C# 13.0, developers can also define property and indexer definitions and their implementations. partial
Separate into two files. Both parts must implement the same combination of getters and setters with the same visibility and the same types.
A concrete example: if a property has both a public getter and a public setter in one part of a class, these must also be present and public in the other part. But where an automatic property is used in one part, an explicit implementation may exist in another part.
Partial properties and partial indexes, like partial classes and partial methods, cannot be merged from multiple projects/assemblies. All parts must be in one project!
New features in code examples
The following listings show an example of a partitioned class with a partial method and partial property and partial index.
The first code snippet shows only the first part of the partial class with property definitions. ID
, Indexer
And Print()
,
using System.Text.Json.Serialization;
namespace NET9_Console.CS13;
///
public partial class PersonWithAutoID
{
// NEU: Partielles Property --> kein "Convert to Full Property"
public partial int ID { get; set; }
// NEU: Partieller Indexer
public partial string this(int index) { get; }
// "Normales Property"
public string Name { get; set; }
// Partielle Methode (gab es vorher schon)
public partial void Print();
}
For getters and setters in the second part of the partial class ID
and this Indexer
as well as the method Print()
Implemented:
///
public partial class PersonWithAutoID
{
int counter = 0;
// Implementierung des Partial Property
private int iD;
public partial int ID
{
get
{
if (iD == 0) iD = ++counter;
return iD;
}
set
{
if (ID > 0) throw new ApplicationException("ID ist bereits gesetzt");
iD = value;
}
}
// Implementierung des Partial Indexer
public partial string this(int index)
{
get
{
return index switch
{
0 => ID.ToString(),
1 => Name,
_ => throw new IndexOutOfRangeException()
};
}
}
// Implementierung der Partial Method
public partial void Print()
{
Console.WriteLine($"{this.ID}: {this.Name}");
}
}
The following code implements the composite class User PersonWithAutoID
,
///
public class CS13_PartialPropertyAndIndexerDemoClient
{
public void Run()
{
CUI.Demo(nameof(CS13_PartialPropertyAndIndexerDemoClient));
CS13.PersonWithAutoID p = new() { Name = "Holger Schwichtenberg" };
p.Print(); // 1: Holger Schwichtenberg
CUI.H2("Versuch, die ID neu zu setzen, führt zum Fehler:");
try
{
p.ID = 42;
}
catch (Exception ex)
{
CUI.Error(ex); // System.ApplicationException: ID ist bereits gesetzt
}
CUI.Print($"Nutzung des Indexers: {p(0)}: {p(1)} ");
}
}
(rme)