Создание объектов без вызова конструктора¶
Рассмотрим малоизвестную функцию служб компилятора .NET, которая позволит вам создать “неинициализированный” экземпляр объекта без вызова каких-либо его конструкторов или инициализаторов свойств.
Во-первых, вам нужно будет сослаться на пространство имён System.Runtime.CompilerServices. Оно содержит класс RuntimeHelpers со статическим методом GetUnitializedObject. Посмотрим, как это работает на практике.
using System;
using System.Runtime.CompilerServices;
var o = RuntimeHelpers
.GetUninitializedObject(typeof(Something));
if (o is Something smth)
{
Console.WriteLine(smth.GetName());
Console.WriteLine(smth.Name ?? "(null)");
}
public class Something
{
public string? Name { get; } = "John";
public Something(string? name)
{
this.Name = name;
}
public string GetName() => Name ?? "Jane";
}
Этот код, как и ожидается, выведет:
В приведённом выше примере создаётся экземпляр Something без вызова конструктора объекта. Инициализатор свойства также не вызывается, поэтому свойство Name по-прежнему имеет значение null. Однако, возможно вызвать как метод GetName, так и обратиться к свойству Name.
Что это значит?¶
Этот подход открывает возможность для разработчиков фреймворков использовать наследование и реализацию интерфейса для настройки элементов во фреймворке. Например, он используется в Fast Endpoints, который позволяет создавать конечные точки веб-сайтов или API в виде классов, а не методов контроллеров. Для внедрения зависимостей в класс конечной точки, создаётся неинициализированный экземпляр класса, а затем вызывается общий метод Configure, который обнаруживает необходимые зависимости и внедряет их.
Тем не менее, этот подход может привести к ошибкам, которые может быть трудно диагностировать. Например, приведённый выше код класса инициализирует свойство Name, но эта инициализация никогда не происходит, что приводит к результату (null) на выходе.
Ссылки¶
https://khalidabuhakmeh.com/create-dotnet-objects-without-calling-the-constructor
Дата создания : 1 августа 2022 г.