English 中文(简体)
Easy way to implement memcpy() like CopyTo in C#
原标题:
  • 时间:2009-12-22 21:18:57
  •  标签:
  • c#
  • memcpy

Is there an "easy" way to implement something like CopyTo() to MemberwiseCopy (instead of Clone() or MemberwiseClone) in C#? I don t want to create a new object, as I want everyone holding the old one to be able to see the attributes of the new one, which may be completely different. While most of these derive from a parent class which could hold some abstract function, I don t want to write a few hundred lines of code just to copy every member one by one. Which may need to be copied over all (bad design, but its not mine, nor is it being rewritten). It seems like Microsoft would have created an interface for this or have I greatly missed out on something?

最佳回答

I think the serialization/deserialization is the "easiest" way to do this. Additionaly, there s a faster way to do it, using pinned handles.

You could use Marshal & GCHandle like such (from this link ):

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; 
} 
问题回答

I don t get the question. Sounds like you just want to create a reference to an existing object.

Variables to objects in C# merely hold a reference to the object, so when you assign a variable to an existing object, you re still accessing the same object.

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

For the above code, y.MyProperty=="hello" as well.

Are you trying to get a deep copy, i.e., one where every field with a reference type is also set to a MemberwiseClone() of the originally-referenced object, ad infinitum?

You could use serialization into a memory stream and deserialization back to an instance.

We have such a "DeepCopy" method in our project. It is kind of risky. We started to implement copy-property-methods or copy constructors into our classes because it is more reliable and gives more control at the end.

If you want to overwrite all of the existing fields of an object with the values from another instance, there is no easy way to do it. It can be done if you re willing to write some wacky reflection code to visit each field of the object and copy the values. But it would be fragile and messy.

Furthermore, to do it correctly, you would need to walk the inheritance tree of the object and perform the same assignment operations as well.

Finally, if the object contains readonly field, it may be impossible to copy the exact state of another instance, and you will be forced to decide whether inconsistent copies are an acceptable outcome of the copy.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签