MemberWiseClone如何使用克隆属性创建新对象?

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

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

它基本上在MemberwiseClone MSDN 文档中解释:

MemberwiseClone方法通过创建新对象,然后将当前对象的非静态字段复制到新对象来创建浅表副本。 如果字段是值类型,则执行字段的逐位复制。 如果字段是引用类型,则复制引用但引用的对象不是; 因此,原始对象及其克隆引用相同的对象。

上述的实际实现由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; } 

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

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

OP增加:请参阅Ivan的评论,以获得我正在寻求的进一步解释。 我认为这些部分是他的答案,并会基于他们接受。