TGViewer
.NET Разработчик .NET Разработчик @netdeveloperdiary · 6.77K subscribers
Post #2050 2.07K
День 1693. #ЧтоНовенького
Доступ к Закрытым Членам Класса без Рефлексии в .NET 8
Закрытые члены класса в C# создаются для того, чтобы к ним нельзя было получить доступ извне. Но если нельзя, а очень хочется… то в .NET 8 появился ещё один способ получить к ним доступ без использования рефлексии.

Рассмотрим следующий класс:
class Sample
{
// Конструкторы
private Sample() { }
private Sample(int value) { }

// Поле
private int field1 = 1;

// Статическое поле
private static int staticField = 2;

// Методы
private int Method(int value) => value;
private static int StaticMethod(int value) => value;
}

.NET 8 предоставляет новый атрибут [UnsafeAccessor]. Чтобы получить доступ к закрытому члену, вы можете объявить внешний (extern) метод с атрибутом [UnsafeAccessor], чтобы объявить метод доступа для закрытого члена. Реализация метода, аннотированного этим атрибутом, будет предоставлена средой выполнения на основе информации в атрибуте и сигнатуры метода, к которому применяется атрибут. Обратите внимание, что UnsafeAccessor менее функционален, чем рефлексия. Например, вы не можете получить доступ к свойствам, а также обобщённые типы пока не полностью поддерживаются.

Конструкторы
var sample1 = CallConstructor();
var sample2 = CallConstructorWithArg(1);

// Возвращаемый тип метода должен быть типом класса
[UnsafeAccessor(
UnsafeAccessorKind.Constructor)]
extern static Sample CallConstructor();

[UnsafeAccessor(
UnsafeAccessorKind.Constructor)]
extern static Sample CallConstructorWithArg(int value);

Методы
var sample = CallConstructor();
Console.WriteLine(Method(sample, 1));

// Первый аргумент – экземпляр класса
[UnsafeAccessor(
UnsafeAccessorKind.Method,
Name = "Method")]
extern static int
Method(Sample @this, int value);

В статических методах так же. Несмотря на то, что экземпляр не требуется, среда выполнения должна знать тип:
Console.WriteLine(StaticMethod(null, 2));

[UnsafeAccessor(
UnsafeAccessorKind.StaticMethod,
Name = "StaticMethod")]
extern static int StaticMethod(Sample @this, int value);

Поля
Используем "ref", чтобы получить ссылку на поле для чтения и записи в него:
[UnsafeAccessor(UnsafeAccessorKind.Field, 
Name = "field1")]
extern static ref int
GetField(Sample @this);

var sample = CallConstructor();
_ = GetField(sample);
GetField(sample) = 42;

В readonly поля также возможна запись, как и при использовании рефлексии.

Аналогично со статическими полями. Как и для статических методов, необходим аргумент с типом класса:
[UnsafeAccessor(
UnsafeAccessorKind.StaticField,
Name = "staticField")]
extern static ref int
GetStaticField(Sample @this);

_ = GetStaticField(sample);

Вы можете записывать в static readonly поля, но с осторожностью. Эти поля очень похожи на константы для JIT. Поэтому запись значения в них может приводить к непредсказуемому поведению, т.к. значение может не читаться повторно в дальнейшем. Заметьте, что это невозможно при использовании рефлексии.

Помните, что имя атрибута начинается с "Unsafe", потому что позволяет делать небезопасные вещи.

Источник: https://www.meziantou.net/accessing-private-members-without-reflection-in-csharp.htm
  • 👍 11
More from @netdeveloperdiary
  1. Oct 10, 2026День 2810. #ЧтоНовенького #VSCode Более Быстрый и Лёгкий C# Dev Kit Мы, разработчики, люби…
  2. Oct 9, 2026День 2809. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Окончание Начало 3.…
  3. Oct 8, 2026День 2808. #Карьера 5 Навыков, Которые Помогут Быстрее Стать Сеньором. Начало В ИТ есть се…
  4. Oct 7, 2026День 2807. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Окончание Нач…
  5. Oct 6, 2026🦈 Открытое собеседование на Middle C# | 6 октября, 19:00 МСК Приглашаем на открытое собес…
  6. Oct 6, 2026День 2806. #ЗаметкиНаПолях Типы Коллекций в .NET, Которые Стоит Попробовать. Начало Больши…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →