New in .NET 10.0 [6]: Generic extension blocks in C# 14.0

The extension blocks in C# 14.0 can also contain generic type parameters.

listen Print view
C# as a character

(Image: Pincasso / Shutterstock.com)

1 min. read
By
  • Dr. Holger Schwichtenberg

I introduced extension blocks with the keyword extension in the previous installment of the series on .NET 10.0. An extension block can have one or more generic type parameters (optionally including constraints with where):

extension<T>(List<T> source) { … }

or

extension<T>(List<T> source) where T : INumber<T> { … }
The Dotnet Doctor – Holger Schwichtenberg
Der Dotnet-Doktor – Holger Schwichtenberg

Dr. Holger Schwichtenberg is the technical director of the expert network www.IT-Visions.de, which supports numerous medium-sized and large companies with consulting and training services as well as software development, drawing on the expertise of 53 renowned experts. Thanks to his appearances at numerous national and international conferences, as well as more than 90 specialist books and over 1,500 specialist articles, Holger Schwichtenberg is one of the best-known experts for .NET and web technologies in Germany.

The following code shows a class with extension blocks for List<T>, where T is restricted to numbers, via where T : INumber<T>:

public static class MyExtensions
{
 extension<T>(List<T> source) where T : INumber<T> // <-- Receiver Ein Erweiterungsblock darf eine oder mehrere generische Typparameter (optional inklusive Constraint) besitzen!!!
 {
  public List<T> WhereGreaterThan(T threshold)
           => source.Where(x => x > threshold).ToList();
 
  public bool IsEmpty
           => !source.Any();
 
  /// <summary>
  /// Erweitern um eine Instanz-Eigenschaft mit Getter und Setter
  /// </summary>
  public int Size
  {
   get { return source.Count; }
   set
   {
    while (value < source.Count) source.RemoveAt(source.Count - 1);
    if (value > source.Count) source.AddRange(Enumerable.Repeat(default(T)!, value - source.Count).ToList());
   }
  }
 
  // NEU: OperatorĂĽberladung als Extension und neu ist auch, dass man += ĂĽberladen kann
  public void operator +=(int count)
  {
   source.Size = source.Count + count;
  }
 
  // NEU: OperatorĂĽberladung als Extension und neu ist auch, dass man -= ĂĽberladen kann
  public void operator -=(int count)
  {
   source.Size = source.Count - count;
  }
 
  // NEU: OperatorĂĽberladung als Extension und neu ist auch, dass man ++ ĂĽberladen kann
  public void operator ++()
  {
   source.Size += 1;
  }
 }
}

The following code calls the extension methods for List<int>:

public void Run()
 {
  CUI.Demo(nameof(CS14_ExtensionDemo) + ": Collection");
 
  var list = new List<int> { 1, 2, 3, 4, 5 };
  var large = list.WhereGreaterThan(3);
  Console.WriteLine(large.IsEmpty);
  if (large.IsEmpty)
  {
   Console.WriteLine("Keine Zahlen größer als 3!");
  }
  else
  {
   Console.WriteLine(large.Count + " Zahlen sind größer als 3!");
  }
 
  CUI.H2("list.Size = 10");
  // Das klappt: Die Liste wird auf 10 Elemente mit Nullen aufgefĂĽllt
  list.Size = 10;
  foreach (var x in list)
  {
   CUI.OL(x, separator: " = ");
  }
 
  CUI.H2("list.Size -= 2");
  list.Size -= 2;
  bool restart = true;
  foreach (var x in list)
  {
   CUI.OL(x, separator: " = ", restartCounter: restart);
   restart = false;
  }
 
  CUI.H2("list.Size++");
  list.Size++;
  restart = true;
  foreach (var x in list)
  {
   CUI.OL(x, separator: " = ", restartCounter: restart);
   restart = false;
  }
 }

Videos by heise

The code produces the following output:

Output of the example code

(mki)

Don't miss any news – follow us on Facebook, LinkedIn or Mastodon.

This article was originally published in German. It was translated with technical assistance and editorially reviewed before publication.