Создание копии объекта в С#
Возможный дубликат:
Как вы делаете глубокую копию объекта в .Net(специально для С#)?
Пожалуйста, посмотрите на код ниже (выдержка из книги С#):
namespace Example
{
class MyClass
{
public int val;
}
struct myStruct
{
public int val;
}
class Program
{
static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = objectA;
objectA.val = 10;
objectB.val = 20;
myStruct structA = new myStruct();
myStruct structB = structA;
structA.val = 30;
structB.val = 40;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.WriteLine("structA.val = {0}", structA.val);
Console.WriteLine("structB.val = {0}", structB.val);
Console.ReadKey();
}
}
}
Я понимаю, что он выводит результат ниже
objectA.val = 20
objectA.val = 20
structB.val = 30
structB.val = 40
Последние две строки вывода у меня не проблема, но первые два говорят мне, что objectA
и objectB
указывают на один и тот же блок памяти (поскольку на С# объекты являются ссылочными типами).
Вопрос заключается в том, как сделать objectB
копию objectA
, чтобы она указывала на другую область памяти. Я понимаю, что попытки назначить своих членов могут не работать, поскольку эти члены также могут быть ссылками. Итак, как мне сделать objectB
совершенно другой объект из objectA
?
Спасибо
Ответы
Ответ 1
Нет встроенного способа. Вы можете использовать MyClass интерфейс IClonable
(но он устарел), или просто написать собственный метод копирования/клонирования. В любом случае вам придется написать код.
Для больших объектов вы можете рассмотреть сериализацию + десериализацию (через MemoryStream), чтобы повторно использовать существующий код.
Каким бы ни был метод, тщательно подумайте о том, что означает "копия". Как глубоко он должен идти, есть ли поля идентификаторов, которые будут исключены и т.д.
Ответ 2
Вы можете сделать:
class myClass : ICloneable
{
public String test;
public object Clone()
{
return this.MemberwiseClone();
}
}
то вы можете сделать
myClass a = new myClass();
myClass b = (myClass)a.Clone();
N.B. MemberwiseClone()
Создает неглубокую копию текущего объекта System.Object.
Ответ 3
Самый простой способ сделать это - написать конструктор копирования в классе MyClass.
Что-то вроде этого:
namespace Example
{
class MyClass
{
public int val;
public MyClass()
{
}
public MyClass(MyClass other)
{
val = other.val;
}
}
}
Второй конструктор просто принимает параметр своего типа (тот, который вы хотите скопировать) и создает новый объект, назначенный с тем же значением
class Program
{
static void Main(string[] args)
{
MyClass objectA = new MyClass();
MyClass objectB = new MyClass(objectA);
objectA.val = 10;
objectB.val = 20;
Console.WriteLine("objectA.val = {0}", objectA.val);
Console.WriteLine("objectB.val = {0}", objectB.val);
Console.ReadKey();
}
}
выход:
objectA.val = 10
objectB.val = 20
Ответ 4
У вас уже есть вопрос об этом, вы могли бы прочитать его
Глубокие объекты клонирования
Нет метода Clone(), который существует в Java, например, но вы можете включить конструктор копирования в свои кланы, что еще один хороший подход.
class A
{
private int attr
public int Attr
{
get { return attr; }
set { attr = value }
}
public A()
{
}
public A(A p)
{
this.attr = p.Attr;
}
}
Это будет пример, копирующий член "Attr" при создании нового объекта.