0

是否有一种“简单”的方法可以在 C#中实现类似CopyTo()to MemberwiseCopy(而不是Clone()or )的东西?MemberwiseClone我不想创建一个新对象,因为我希望每个持有旧对象的人都能看到新对象的属性,这可能会完全不同。虽然其中大多数都派生自可以包含一些抽象函数的父类,但我不想编写几百行代码来一一复制每个成员。这可能需要全部复制(糟糕的设计,但它不是我的,也没有被重写)。微软似乎会为此创建一个界面,还是我错过了一些东西?

4

4 回答 4

5

我不明白这个问题。听起来您只想创建对现有对象的引用。

在 C# 中,对象的变量仅包含对对象的引用,因此当您将变量分配给现有对象时,您仍然在访问同一个对象。

Object x = new Object();
Object y = x;
x.MyProperty = "hello";

对于上面的代码,y.MyProperty=="hello" 也是如此。

您是否正在尝试获取深层副本,即具有引用类型的每个字段也设置为原始引用对象的 MemberwiseClone() 无限期?

于 2009-12-22T21:27:15.297 回答
4

我认为序列化/反序列化是做到这一点的“最简单”的方法。此外,还有一种更快的方法,使用固定手柄。

您可以像这样使用 Marshal & GCHandle(来自此链接):

public static object RawDeserializeEx( byte[] rawdatas, Type anytype ) 
{ 
 int rawsize = Marshal.SizeOf( anytype ); 
 if( rawsize > rawdatas.Length ) 
  return null; 
 GCHandle handle = GCHandle.Alloc( rawdatas, GCHandleType.Pinned ); 
 IntPtr buffer = handle.AddrOfPinnedObject(); 
 object retobj = Marshal.PtrToStructure( buffer, anytype ); 
 handle.Free(); 
 return retobj; 
} 

public static byte[] RawSerializeEx( object anything ) 
{ 
 int rawsize = Marshal.SizeOf( anything ); 
 byte[] rawdatas = new byte[ rawsize ]; 
 GCHandle handle = GCHandle.Alloc( rawdatas, GCHandleType.Pinned ); 
 IntPtr buffer = handle.AddrOfPinnedObject(); 
 Marshal.StructureToPtr( anything, buffer, false ); 
 handle.Free(); 
 return rawdatas; 
} 
于 2009-12-26T13:42:19.800 回答
2

您可以使用序列化到内存流和反序列化回实例。

我们的项目中有这样一个“DeepCopy”方法。这有点冒险。我们开始在我们的类中实现复制属性方法或复制构造函数,因为它更可靠并且最终提供了更多控制。

于 2009-12-22T21:24:17.117 回答
0

如果你想用另一个实例的值覆盖一个对象的所有现有字段,没有简单的方法可以做到。如果您愿意编写一些古怪的反射代码来访问对象的每个字段并复制值,则可以这样做。但这将是脆弱和混乱的。

此外,要正确执行此操作,您还需要遍历对象的继承树并执行相同的赋值操作。

最后,如果对象包含readonly字段,则可能无法复制另一个实例的确切状态,并且您将被迫决定不一致的副本是否是副本的可接受结果。

于 2009-12-22T21:26:55.287 回答