No .NET, há várias formas comuns de implementar uma cópia profunda (deep copy). A cópia profunda significa criar um novo objeto e copiar recursivamente o objeto original e todas as suas referências, em vez de apenas copiar as referências. Neste artigo, vamos explorar os principais métodos para implementar cópia profunda no .NET. Vamos conferir!
1. Usando serialização/deserialização binária
“`csharp
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public static class ObjectCopier
{
public static T DeepCopy<T>(T obj)
{
if (!typeof(T).IsSerializable)
{
throw new ArgumentException(“O tipo deve ser serializável.”, nameof(obj));
}
if (ReferenceEquals(obj, null))
{
return default;
}
IFormatter formatter = new BinaryFormatter();
using (var stream = new MemoryStream())
{
formatter.Serialize(stream, obj);
stream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(stream);
}
}
}
“`
2. Usando serialização JSON (Newtonsoft.Json ou System.Text.Json)
“`csharp
// Usando Newtonsoft.Json
using Newtonsoft.Json;
public static T DeepCopy<T>(T obj)
{
var json = JsonConvert.SerializeObject(obj);
return JsonConvert.DeserializeObject<T>(json);
}
// Usando System.Text.Json (recomendado a partir do .NET Core 3.0)
using System.Text.Json;
public static T DeepCopy<T>(T obj)
{
var json = JsonSerializer.Serialize(obj);
return JsonSerializer.Deserialize<T>(json);
}
“`
3. Implementando a interface ICloneable (manual)
“`csharp
public class MyClass : ICloneable
{
public int Value { get; set; }
public MyOtherClass Other { get; set; }
public object Clone()
{
var copy = (MyClass)MemberwiseClone(); // cópia superficial
copy.Other = (MyOtherClass)Other.Clone(); // cópia profunda da referência
return copy;
}
}
public class MyOtherClass : ICloneable
{
public string Name { get; set; }
public object Clone()
{
return MemberwiseClone(); // cópia superficial (apenas tipos de valor)
}
}
“`
4. Usando AutoMapper (para objetos complexos)
“`csharp
using AutoMapper;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<MyClass, MyClass>();
cfg.CreateMap<MyOtherClass, MyOtherClass>();
});
var mapper = config.CreateMapper();
var copy = mapper.Map<MyClass>(original);
“`
5. Considerações importantes
* Métodos baseados em serialização exigem que todas as classes envolvidas sejam serializáveis (com o atributo `[Serializable]` ou compatíveis com JSON).
* Referências circulares podem causar estouro de pilha ou exceções de serialização.
* Desempenho: para gráficos de objetos grandes, a serialização pode ser lenta.
* Tipos especiais como delegados ou objetos COM podem não ser copiados corretamente.
6. Métodos recomendados
* Para objetos simples: use serialização JSON (System.Text.Json tem melhor desempenho).
* Para gráficos de objetos complexos: considere implementar `ICloneable` ou usar AutoMapper.
* Para cenários com alta exigência de desempenho: implemente a lógica de cópia profunda manualmente.
A escolha do método mais adequado depende dos requisitos do seu projeto, da complexidade dos objetos e das restrições de desempenho.
Tài nguyên này được người dùng tải lên và nội dung được lấy từ Internet. Trang web này chỉ giới thiệu miễn phí để học tập và chia sẻ. Nếu có bất kỳ vấn đề bản quyền hoặc vấn đề nào khác, vui lòng liên hệ với biên tập viên của trang web này để xử lý!
Lưu ý quan trọng: : Nếu phần mềm liên quan đến thanh toán, thành viên, nạp tiền, v.v., thì đây là những hành động của nhà phát triển phần mềm hoặc công ty sở hữu phần mềm đó và không liên quan gì đến trang web này. Cư dân mạng cần phải tự đưa ra phán đoán của mình.