Перейти к содержанию

Создание объектов без вызова конструктора

Рассмотрим малоизвестную функцию служб компилятора .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";
}

Этот код, как и ожидается, выведет:
Jane
(null)

В приведённом выше примере создаётся экземпляр Something без вызова конструктора объекта. Инициализатор свойства также не вызывается, поэтому свойство Name по-прежнему имеет значение null. Однако, возможно вызвать как метод GetName, так и обратиться к свойству Name.

Что это значит?

Этот подход открывает возможность для разработчиков фреймворков использовать наследование и реализацию интерфейса для настройки элементов во фреймворке. Например, он используется в Fast Endpoints, который позволяет создавать конечные точки веб-сайтов или API в виде классов, а не методов контроллеров. Для внедрения зависимостей в класс конечной точки, создаётся неинициализированный экземпляр класса, а затем вызывается общий метод Configure, который обнаруживает необходимые зависимости и внедряет их.

Тем не менее, этот подход может привести к ошибкам, которые может быть трудно диагностировать. Например, приведённый выше код класса инициализирует свойство Name, но эта инициализация никогда не происходит, что приводит к результату (null) на выходе.

Ссылки

https://khalidabuhakmeh.com/create-dotnet-objects-without-calling-the-constructor


Последнее обновление : 9 июля 2023 г.
Дата создания : 1 августа 2022 г.

Комментарии

Комментарии