16

我的问题相对简单,我感觉 GetUninitializedObject(type) 方法不会在不调用任何构造函数的情况下生成给定类型的新实例,而是生成一个行为与正确对象相似的新对象(具有相同的结构)和显然具有相同的类型(但内部仍然是一个对象)。

我说因为最近我尝试使用 GetUninitializedObject 克隆一个 Form.Button 以生成我在该操作期间需要的类型的新实例(我在源对象上递归操作),我的结果具有正确的结构(和即时窗口还说它具有正确的类型)但是如果我尝试执行 MyForm.Components.Add(clonedButton),我会收到一条异常消息:“无法将'System.Object'类型的对象转换为'ControlCollection'”(但我'已经检查了 clonedButton 类型是 Button 并且它的继承也是正确的,我手动检查了克隆按钮内的几乎所有结构,并与源 Button 对象匹配,并且我已经访问了公共和私有字段)。

所以这就是我的问题的原因(因为我在 javascript 中遇到了类似的问题,当我在相同的克隆上下文中生成对象形式 base Object 然后添加具有正确名称和结构的字段时,编译器发现了我的技巧,看什么是调用每个实例的构造函数,所以我认为它可能是类似的情况),如果有人可以向我解释 GetUninitializedObject() 背后的魔法,它应该会有很大帮助(提前感谢)。

4

1 回答 1

24

(但在内部仍然是一个对象)

不,他们没有。你已经为你所看到的行为提出了一个合理的解释,但这不是正确的解释。

Button您从中获得的是FormatterServices.GetUninitializedObject(typeof(Button))真实的Button,并且在所有方面都表现得与其他任何方面一样Button,除了它的构造函数没有被调用。问题在于,Button当它的构造函数没有被调用时,它就不能工作,而且你试图伪造它的尝试与真实的东西不够接近。

Button通过在未初始化的对象上显式调用构造函数,您可以看到按钮是真实的:

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

并且您将能够使用此按钮执行您原本可以执行的所有操作。

于 2013-09-23T21:13:51.600 回答