【问题标题】:Function to clone an arbitrary object克隆任意对象的函数
【发布时间】:2012-08-29 02:10:13
【问题描述】:

我正在寻找一种方法来克隆在编译时(或运行时,我认为)未知的对象。问题的确切措辞是“编写一个可以克隆任意对象的函数”例如

  • 将未知对象传递给函数。
  • 返回对象的深层副本。

我猜我需要使用反射来读取函数和变量,然后是一些如何创建一个新对象并将这些值分配给它的方法。我可以只使用 Type.GetType() 来查找类型并创建一个新实例,然后使用这个 known 对象的复制构造函数。但是我不确定给定的类是否会实现(深度),或者问题是否要求这样的解决方案(我不明白所需的结果是什么,这无济于事!)。

有人可以指导我朝着正确的方向前进吗?需要类/接口和伪代码(如果您觉得大方的话)来实现这一目标?

【问题讨论】:

  • 你可以序列化和反序列化回来。
  • @L.B 是的,但是大多数序列化程序都有先决条件和限制;它们不需要扩展到任意对象。
  • 这是个好主意,你可能有一个像where T : ISerializable这样限制的泛型方法,只是为了确保你不会有问题
  • Create a Deep Copy in C#的可能重复
  • @AndreCalil 不会解决它,因为这只是将条件放在根对象上 - 它不能保证更大图的任何事情。另外:大多数可序列化类型不应实现ISerializable

标签: c# reflection clone


【解决方案1】:

您可以简单地通过SerializeDeserialize 一个对象来进行克隆。
以下函数将执行此操作:

public object Clone(object obj)
{
    MemoryStream ms = new MemoryStream();
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(ms, obj);
    ms.Position = 0;
    object obj_clone = bf.Deserialize(ms);
    ms.Close();
    return obj_clone;
}

【讨论】:

  • 需要注意的是,这里有一些注意事项;它仅适用于 [Serializable] 类型,并且在许多情况下可能会出现问题(事件是一个主要示例)。但是,它与您可以找到问题的一般解决方案差不多。
【解决方案2】:

这可以通过使用来实现

Type newObjectType = orgObject.GetType()

然后调用 Activator.CreateInstance(newObjectType)。然后,您要做的是遍历对象的所有属性并将它们设置在新对象上。这也可以通过反射来完成。

遍历 orgObject.GetType().GetProperties() 中的每个 PropertyInfo 并在新对象上设置值。

这确实应该创建对象的“深层”副本,与它是什么类型无关。

编辑: 我上面解释的方法的未经测试的代码示例。

Type newObjectType = orgObject.GetType();
object newObject = Activator.CreateInstance(newObjectType);

foreach (var propInfo in orgObject.GetType().GetProperties())
{
    object orgValue = propInfo.GetValue(orgObject, null);

    // set the value of the new object
    propInfo.SetValue(newObject, orgValue, null);
}

希望你能弄明白!

【讨论】:

  • 它可以比这更微妙;例如,get-only / set-only 属性、字段不与公共属性 1:1 映射的类型、没有无参数构造函数的类型、循环图等......这将处理一个 小子集 个案例,但对于“任意”对象,IMO 不会是一个令人满意的答案。
  • 在另一个对象内部复制一个对象的引用并不意味着深度复制。
  • 同意@L.B. - 这是一个非常浅的副本。
  • 这是一个非常模糊的作业问题。除了要求澄清规范外,我看不到任何前进的方向。 this 甚至可能是作业旨在教授的内容之一。我的意思是,这让他检查了深拷贝和浅拷贝之间的区别。如果您可以使用 deal-with-bad-spec 并详细了解反射,那么它实际上是一个 great 作业问题。单手克隆的声音是什么?
猜你喜欢
  • 2021-06-30
  • 2011-11-07
  • 1970-01-01
  • 1970-01-01
  • 2013-01-03
  • 2017-02-11
  • 2011-07-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多