![Neu in .NET 9.0 [27]: Erweiterter Zugriff über Wrapper-Klassen](/uploads/images/20250627/da97a91b5c3aca4c2b.png)
Neu in .NET 9.0 [27]: Erweiterter Zugriff über Wrapper-Klassen
Der Zugriff auf nicht-öffentliche Mitglieder einer Klasse über eine Wrapper-Klasse ("Accessor"), die [UnsafeAccessorAttribute]
nutzt, wurde in .NET 8.0 eingeführt.
Dr. Holger Schwichtenberg ist technischer Leiter des Expertennetzwerks www.IT-Visions.de, das mit 53 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratungen und Schulungen sowie bei der Softwareentwicklung unterstützt. Durch seine Auftritte auf zahlreichen nationalen und internationalen Fachkonferenzen sowie mehr als 90 Fachbücher und mehr als 1500 Fachartikel gehört Holger Schwichtenberg zu den bekanntesten Experten für .NET und Webtechniken in Deutschland.
Nun funktioniert das auch mit generischen Parametern:
using System.Runtime.CompilerServices;
namespace NET9_Console.FCL90_UnsafeAccessor;
/// Der Zugriff auf nicht-öffentliche Mitglieder einer Klasse über eine Wrapper-Klasse, die [UnsafeAccessorAttribute] nutzt, wurde in .NET 8.0 eingeführt. Neu in .NET 9.0: Nun funktioniert dies auch mit generischen Parametern.
/// <summary>
/// Eine Klasse mit zwei privaten Mitgliedern, die wir über UnsafeAccessorAttribute von Außen nutzen wollen
/// </summary>
/// <typeparam name="T"></typeparam>
public class Printer<T>
{
private T _data = default;
private void Print<PreTextType>(PreTextType preText) { CUI.Green(preText.ToString()); Console.WriteLine(_data.ToString()); }
public override string ToString()
{
return "Data=" + (_data?.ToString() ?? "(leer)");
}
}
/// <summary>
/// Accessor für Printer<T>, um auf private Mitglieder zugreifen zu können
/// </summary>
class PrinterAccessor<T>
{
[UnsafeAccessor(UnsafeAccessorKind.Field, Name = "_data")] // Zugriff auf das private Feld
public extern static ref T GetSetPrivateField(Printer<T> p);
[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "Print")] // Zugriff auf die private Methode
public extern static void CallPrivatePrint<PreTextType>(Printer<T> p, PreTextType preText);
}
/// </summary>
class Client
{
public void Run()
{
CUI.Demo(nameof(FCL90_UnsafeAccessor));
CUI.H2("Erzeuge das Objekt mit den privaten Mitgliedern");
Printer<Consultant> printer = new Printer<Consultant>();
Console.WriteLine("Vorher:\n" + printer.ToString());
// Zugriff auf das Objekt via Accessor
CUI.H2("Setzen eines privaten Feldes");
ref Consultant data = ref PrinterAccessor<Consultant>.GetSetPrivateField(printer);
data = new Consultant() { ID = 42, FullName = "Dr. Holger Schwichtenberg", PersonalWebsite = "www.dotnet-doktor.de", Address = new Address() { City = "Essen" }, Languages = ["C#", "VB.NET", "JavaScript/TypeScript"] };
CUI.Success("Wert für Private Field gesetzt!");
Console.WriteLine("Kontrolle über Zugriff auf das öffentliche ToString():\n" + printer.ToString());
// Methode aufrufen
CUI.H2("Aufruf einer privaten Methode mit generischen Parametern: CallPrivatePrint<string>()");
PrinterAccessor<Consultant>.CallPrivatePrint<string>(printer, "Sie werden beraten von:");
}
}