Простой способ реализовать memcpy() как CopyTo в C#

StackOverflow https://stackoverflow.com/questions/1949235

  •  21-09-2019
  •  | 
  •  

Вопрос

Есть ли "простой" способ реализовать что-то вроде CopyTo() Для MemberwiseCopy (вместо Clone() или MemberwiseClone) в C #?Я не хочу создавать новый объект, так как я хочу, чтобы все, у кого есть старый, могли видеть атрибуты нового, которые могут быть совершенно другими.Хотя большинство из них являются производными от родительского класса, который мог бы содержать какую-то абстрактную функцию, я не хочу писать несколько сотен строк кода только для того, чтобы скопировать каждый элемент один за другим.Который, возможно, потребуется скопировать поверх всего (плохой дизайн, но это не мое, и он не переписывается).Похоже, что Microsoft создала бы интерфейс для этого, или я что-то сильно упустил?

Это было полезно?

Решение

Я думаю, что сериализация / десериализация - это "самый простой" способ сделать это.Кроме того, есть более быстрый способ сделать это, используя закрепленные маркеры.

Вы могли бы использовать 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; 
} 

Другие советы

Я не понимаю вопроса.Похоже, вы просто хотите создать ссылку на существующий объект.

Переменные для объектов в C # просто содержат ссылку на объект, поэтому, когда вы присваиваете переменную существующему объекту, вы по-прежнему обращаетесь к тому же объекту.

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

Для приведенного выше кода также используйте y.MyProperty=="hello".

Вы пытаетесь получить глубокую копию, то есть такую, где каждому полю со ссылочным типом также присваивается значение MemberwiseClone() объекта с исходной ссылкой, до бесконечности?

Вы могли бы использовать сериализацию в поток памяти и десериализацию обратно в экземпляр.

У нас есть такой метод "DeepCopy" в нашем проекте.Это довольно рискованно.Мы начали внедрять методы копирования свойств или конструкторы копирования в наши классы, потому что это более надежно и дает больше контроля в конце.

Если вы хотите перезаписать все существующие поля объекта значениями из другого экземпляра, нет легко способ сделать это.Это можно сделать, если вы готовы написать какой-нибудь дурацкий код отражения, чтобы посетить каждое поле объекта и скопировать значения.Но это было бы хрупко и беспорядочно.

Кроме того, чтобы сделать это правильно, вам нужно будет пройти по дереву наследования объекта и выполнить те же операции присваивания.

Наконец, если объект содержит readonly поле, может оказаться невозможным скопировать точное состояние другого экземпляра, и вы будете вынуждены решить, являются ли несовместимые копии приемлемым результатом копирования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top