Bir sarıcı sınıfında (“Accessor”) bir sınıfın kamuya açık olmayan üyelerine erişim [UnsafeAccessorAttribute] Kullanılan .NET 8.0'da tanıtıldı.
Holger Schwichtenberg, 53 ünlü uzmanla tavsiye ve eğitim yoluyla ve yazılımın geliştirilmesinde çok sayıda orta ve büyük şirketi destekleyen uzmanlar ağının teknik direktörüdür. Çok sayıda ulusal ve uluslararası uzman konferansındaki görünümleri, 90'dan fazla uzman kitabı ve 1.500'den fazla uzman makalesi sayesinde Holger Schwichtenberg, Almanya'daki .NET ve Web teknikleri için en iyi uzmanlardan biridir.
Şimdi bu aynı zamanda genel parametrelerle de çalışıyor:
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:");
}
}
Listenin listesi, sargı sınıfından erişimi gösterir.
(Resim: Ekran görüntüsü (Holger Schwichtenberg))
(RME)
Ne yazık ki, bu bağlantı artık geçerli değil.
Boşa harcanan eşyalara olan bağlantılar, 7 günlük daha büyükse veya çok sık çağrılmışsa gerçekleşmez.
Bu makaleyi okumak için bir Haberler+ paketine ihtiyacınız var. Şimdi yükümlülük olmadan bir hafta deneyin – yükümlülük olmadan!

Holger Schwichtenberg, 53 ünlü uzmanla tavsiye ve eğitim yoluyla ve yazılımın geliştirilmesinde çok sayıda orta ve büyük şirketi destekleyen uzmanlar ağının teknik direktörüdür. Çok sayıda ulusal ve uluslararası uzman konferansındaki görünümleri, 90'dan fazla uzman kitabı ve 1.500'den fazla uzman makalesi sayesinde Holger Schwichtenberg, Almanya'daki .NET ve Web teknikleri için en iyi uzmanlardan biridir.
Şimdi bu aynı zamanda genel parametrelerle de çalışıyor:
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:");
}
}

Listenin listesi, sargı sınıfından erişimi gösterir.
(Resim: Ekran görüntüsü (Holger Schwichtenberg))
(RME)
Ne yazık ki, bu bağlantı artık geçerli değil.
Boşa harcanan eşyalara olan bağlantılar, 7 günlük daha büyükse veya çok sık çağrılmışsa gerçekleşmez.
Bu makaleyi okumak için bir Haberler+ paketine ihtiyacınız var. Şimdi yükümlülük olmadan bir hafta deneyin – yükümlülük olmadan!