Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

4 года назад
Открыть в
День 1235. #ЗаметкиНаПолях Создание Объектов без Вызова Конструктора Вам когда-нибудь требовались результаты экземплярного метода, когда у вас не было необходимых зависимостей для создания экземпляра объекта? Если вы ответили «да», то начнём с того, что вы странный человек. По-хорошему странный, но всё же странный. Несмотря на это, решение есть. Рассмотрим малоизвестную функцию служб компилятора .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) на выходе. Итого Всегда полезно знать, какие варианты есть в распоряжении разработчиков. Однако, использовать каждый инструмент стоит с осторожностью. Источник: khalidabuhakmeh.com/create-…structor