Как FormatterServices.GetUninitializedObject работает внутри?

Мой вопрос относительно прост, я чувствую, что метод GetUninitializedObject (type) не генерирует новый экземпляр данного типа без вызова какого-либо конструктора, но генерирует новый объект, который действует как правильные (имеет тот же структура) и, по-видимому, имеет тот же тип (но внутренне остается объектом).

Я говорю, что, поскольку недавно я попытался клонировать Form.Button с помощью GetUninitializedObject для генерации новых экземпляров типов, которые мне нужны во время этой операции (я рекурсивно управляю исходным объектом), мой результат имеет правильную структуру ( и немедленные окна также говорят, что он имеет правильный тип), но если я пытаюсь выполнить MyForm.Components.Add(clonedButton), я получаю исключение с сообщением: "Невозможно наложить объект типа" System.Object "на тип" ControlCollection "" (но я проверял тип clonedButton - Button, и его наследования верны, вручную я проверил почти все структуры, внутри клонированной кнопки и сопоставил исходный объект Button, и я получил доступ как к публичным, так и к публичным полям).

Так вот почему мой вопрос (потому что у меня была аналогичная проблема в javascript, когда в том же контексте клонирования я генерирую объектную базовую Object Object, а затем добавляю поле с правильным именем и структурой, компилятор обнаруживает мой трюк что называется вызываемым конструктором каждого экземпляра, поэтому я предположил, что это может быть аналогичная ситуация), если кто-нибудь может объяснить мне магию за GetUninitializedObject(), он должен многое помочь (спасибо заранее).

Ответ 1

(но внутренне остается объектом)

Нет, они этого не делают. Вы придумали разумное объяснение поведения, которое вы видите, но это не правильное объяснение.

Button Button - это реальный Button и ведет себя как любой другой Button во всех аспектах, кроме того, что его конструктор не был вызван. Проблема в том, что Button не предназначен для работы, когда его конструктор не вызывается, и ваша попытка подделать его недостаточно близко к реальной вещи.

Вы можете видеть, что кнопка является реальным Button путем явного вызова конструктора на неинициализированном объекте:

var button = (Button)FormatterServices.GetUninitializedObject(typeof(Button));
var constructor = typeof(Button).GetConstructor(Type.EmptyTypes);
constructor.Invoke(button, null);

и вы сможете сделать все с помощью этой кнопки, которую вы могли бы сделать в противном случае.