c# - MemberWiseClone 如何创建具有克隆属性的新对象?

标签 c# dynamic reflection clone

我想创建一个更受限制的 MemberwiseClone 版本,但意识到我自己的 C# 代码可以将属性添加到对象的唯一方法是使用 dynamic,但是不能赋予对象与原始对象相同的类型。我的另一个更丑陋的选择是为新克隆发出源代码并在运行时编译它,但这带来了复杂性。为了使事情简单化,我不关心程序集引用等。

目前我只使用 MemberwiseClone,但我真的很好奇它是如何工作的。我找不到任何反编译源。

最佳答案

它在 MemberwiseClone MSDN documentation 中有基本解释。 :

The MemberwiseClone method creates a shallow copy by creating a new object, and then copying the nonstatic fields of the current object to the new object. If a field is a value type, a bit-by-bit copy of the field is performed. If a field is a reference type, the reference is copied but the referred object is not; therefore, the original object and its clone refer to the same object.

上面的实际实现是由CLR内部实现的。您可以将其视为以下标准 C# 代码的优化变体:

using System.Reflection;
using System.Runtime.Serialization;

public static object CustomMemberwiseClone(object source)
{
    var clone = FormatterServices.GetUninitializedObject(source.GetType());
    for (var type = source.GetType(); type != null; type = type.BaseType)
    {
        var fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
        foreach (var field in fields)
            field.SetValue(clone, field.GetValue(source));
    }
    return clone;
}

即获取实际类型,创建该类型的新实例而不调用任何构造函数,并从源对象复制每个实例字段值。

同样,实际的内部实现是不同的(如评论中所指出的),上面的代码片段只是为了演示原理以及如何通过反射实现具有相同语义的方法(当然会比反射慢得多) CLR 方法)。

由 OP 添加: 请参阅下面 Ivan 的评论,了解我正在寻求的进一步解释。我考虑了他的回答的这些部分,并会根据它们接受它。

关于c# - MemberWiseClone 如何创建具有克隆属性的新对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41998366/

相关文章:

javascript - 脚本不适用于新版本的 jQuery

excel - 变量范围内最后一个填充单元格的返回值

scala - 使用反射和解释器动态解析字符串并在 Scala 中返回一个函数

c# - 在运行时获取继承的对象类型

c# - 如何将集合初始值设定项语法与 ExpandoObject 一起使用?

c# - 多个图像处理程序调用导致 IE 在弹出窗口中挂起

c# - 用 Reflection 找到私有(private)字段?

java - 如何使用泛型类型访问静态内部类中的字段? (非常困难)

c# - C#获取对象地址的方法

c# - 使用双 Foreach 循环输出数据时结果相同