我想创建一个更受限制的 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/