【问题标题】:How FormatterServices.GetUninitializedObject work internally?FormatterServices.GetUninitializedObject 如何在内部工作?
【发布时间】:2013-09-28 21:46:33
【问题描述】:

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

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

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

【问题讨论】:

  • 我确定您也无法将按钮投射到 ControlCollection ;) 请显示有问题的代码行。
  • 它严重违反了适用于您可以用 C# 编写的任何代码的规则。它创建一个对象而不调用构造函数。托管代码中有很大的禁忌,需要支持二进制反序列化。
  • @Vitor 你是对的,我把方法名输入到了问题的正文中

标签: c# clone


【解决方案1】:

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

不,他们没有。您对所看到的行为提出了合理的解释,但这不是正确的解释。

您从FormatterServices.GetUninitializedObject(typeof(Button)) 获得的Button 是一个真正的Button,并且在其他所有方面的行为都与其他Button 相同,只是它的构造函数没有被调用。问题是Button 的构造函数没有被调用时就不能正常工作,而且你伪造它的尝试与真实的东西不够接近。

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

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

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

【讨论】:

    猜你喜欢
    • 2019-01-13
    • 2010-10-14
    • 2012-08-01
    • 2011-12-10
    • 2018-02-10
    • 2014-09-29
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多