В C# функции memcpy эквивалент
У меня есть 2 объекта одного типа, и я хотел бы мелко скопировать одно состояние в другое. В C++ у меня есть memcpy, что здорово. Как я могу сделать это в C#? MemberwiseClone () недостаточно хорош, потому что он создает и возвращает новый объект, и мне нравится копировать в существующий объект. Я думал использовать reflection, но боюсь, что он будет слишком медленным для производственного кода. Я также думал об использовании одного из сериализаторов .Net, но я думаю, что они также создают объект, а не устанавливают существующий один.
Мой Пример:
У меня есть объект шаблона (class not struct), который должен быть обновлен одним из его экземпляров (объекты, сделанные из этого шаблона)
какие идеи?
8 ответов
[edit] относительно вашего разъяснения: Как я понимаю, у вас есть N объектов, каждый из которых имеет (прямую) ссылку на объект шаблона. Вы хотите записать обратно в шаблон, чтобы все объекты "видели" эти изменения.
предложение: реализации шаблона брокера.
class TemplateProvider
{
public MyData Template { get; set; }
}
вместо передачи шаблона передайте поставщику шаблонов объекты.
в simplyfy синтаксис в компоненты, можно добавить (частный/внутренний?) собственность
MyData Template { get { return m_templateProvider.Template; } }
void UpdateTemplate() { m_templateProvider.Template =
(MyData) this.MemberwiseClone(); }
поставщик шаблонов также упрощает блокировку в многопоточных сценариях.
короче говоря, ни в коем случае, если вы не сделаете это сами. Но почему бы не создать новый объект, если вы все равно переопределяете все свойства?
memcopy
и подобные низкоуровневые конструкции не поддержаны в виду того что они подрывают гарантии сделанные окружающей средой.
мелкая копия для структур производится по назначению. Для занятий,MemberwiseClone
- это способ сделать это-но, как вы говорите, это создает новый объект.
для этого нет встроенного способа,и поскольку он потенциально нарушает инкапсуляцию, его следует использовать с осторожностью.
вы можете создать общую процедуру с помощью отражения, но работает ли она или нет, зависит от самого класса. И да, ти будет comparedly медленно.
то, что осталось, поддерживает его с помощью пользовательского интерфейса. Вы можете предоставить общую процедуру "мелкой копии", которая проверяет интерфейс и использует это и возвращается к размышлениям, когда это не так. Это делает функциональность доступной в целом, и вы можете оптимизировать классы, для которых производительность имеет значение позже.
на C#
(и C++
тоже), нет никакой разницы между" новым объектом "и" копией существующего объекта", пока все их члены равны друг другу.
дано:
Int32 a = 5;
, оба действия:
Int32 b = 5;
Int32 b = a;
дайте тот же результат.
как говорится в MSDN reference:
метод MemberwiseClone создает неглубокую копию путем создания нового объекта, а затем копирования нестатических полей текущего объекта к новому объекту.
если поле имеет тип значения, выполняется его побитовая копия.
если поле является ссылочным типом, ссылка копируется, но указанный объект-нет; поэтому исходный объект и его клон ссылаются на один и тот же объект.
, т. е. он делает то же самое, что и memcpy()
на C++
Я думаю, вы могли бы просто сделать что-то вроде:
YourObjectType A = new YourObjectType();
YourObjectType B = a.MemberwiseClone();
Это создаст новый объект внутри метода MemberwiseClone и сделает ссылку на объект B. Полагаю, это служит вашим целям.
namespace WindowsFormsApplication7
{
[Serializable] // just put this in your class
class Mate
{
public string SomeProperty { get; set; }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var mA = new Mate();
mA.SomeProperty = "Hey";
var vf = new BinaryFormatter();
var ns = new MemoryStream();
vf.Serialize(ns, mA);
byte[] vytes = ns.ToArray();
var vfx = new BinaryFormatter();
var nsx = new MemoryStream();
nsx.Write(vytes, 0, vytes.Length);
nsx.Seek(0, 0);
var mB = (Mate)vfx.Deserialize(nsx);
mA.SomeProperty = "Yo";
MessageBox.Show(mA.SomeProperty); // Yo
MessageBox.Show(mB.SomeProperty); // Hey
}
}
}
namespace WindowsFormsApplication7
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
var dt = new DataTable();
dt.Columns.Add("lastname", typeof(string));
dt.Columns.Add("firstname", typeof(string));
dt.Rows.Add("lennon", "john");
dt.Rows.Add("mccartney", "paul");
var ms = new MemoryStream();
var bf = new BinaryFormatter();
bf.Serialize(ms, dt);
byte[] bytes = ms.ToArray();
var bfx = new BinaryFormatter();
var msx = new MemoryStream();
msx.Write(bytes, 0, bytes.Length);
msx.Seek(0, 0);
// doesn't just copy reference, copy all contents
var dtx = (DataTable)bfx.Deserialize(msx);
dtx.Rows[0]["lastname"] = "Ono";
// just copy reference
var dty = dt;
dty.Rows[0]["lastname"] = "Winston";
MessageBox.Show(dt.Rows[0]["lastname"].ToString()); // Winston
MessageBox.Show(dtx.Rows[0]["lastname"].ToString()); // Ono
MessageBox.Show(dty.Rows[0]["lastname"].ToString()); // Winston
}
}
}
Я не могу использовать вновь созданный объект, потому что мне нравится шаблон объект должен быть изменен в соответствии с состоянием одного из его экземпляров (i.e экземпляр, сделанный из этого шаблона)
когда я думаю об этом-очень интересно посмотреть на код реализации метода MemberWiseClone() и посмотреть, как Microsoft решила мой вопрос.
назначение одной структуры другой, для всех намерений и целей, работает ровно как memcpy
в C++ на объектах POD.
Если вы чувствуете, что это не относится к вашей ситуации, я могу заверить вас, что ваш код C++ не соответствовал стандарту (т. е. содержал ошибки в виде неопределенного поведения). Пожалуйста, укажите (на вопрос) какой эффект вы хотите достичь. Это будет более полезно, чем говорить о репликации неопределено поведение на другом языке.