Как глубоко скопировать матрицу в C #? - PullRequest
4 голосов
/ 22 ноября 2011

Я получил List<List<CustomClass>>, где CustomClass является ссылочным типом.

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

Как бы вы сделали это эффективным способом?

Ответы [ 4 ]

4 голосов
/ 22 ноября 2011

Для CustomClass, который реализует ICloneable, это не очень сложно:

var myList = new List<List<CustomClass>>();

//populate myList

var clonedList = new List<List<CustomClass>>();

//here's the beef
foreach(var sublist in myList)
{
   var newSubList = new List<CustomClass>();
   clonedList.Add(newSubList);
   foreach(var item in sublist)
      newSublist.Add((CustomClass)(item.Clone()));
}

Вы можете сделать эту работу аналогично любому методу типа "DeepCopy", если чувствуете, что не хотите внедрять ICloneable (хотя я бы порекомендовал использовать встроенный интерфейс).

3 голосов
/ 22 ноября 2011

Один более простой способ сериализации всего объекта, а затем десериализации еще раз, попробуйте этот метод расширения:

public static T DeepClone<T>(this T source)
{
  if (!typeof(T).IsSerializable)
  {
    throw new ArgumentException("The type must be serializable.", "source");
  }

  // Don't serialize a null object, simply return the default for that object
  if (Object.ReferenceEquals(source, null))
  {
    return default(T);
  }

  IFormatter formatter = new BinaryFormatter();
  Stream stream = new MemoryStream();
  using (stream)
  {
    formatter.Serialize(stream, source);
    stream.Seek(0, SeekOrigin.Begin);
    return (T)formatter.Deserialize(stream);
  }
}

ИСПОЛЬЗОВАНИЕ

List<List<CustomClass>> foobar = GetListOfListOfCustomClass();

List<List<CustomClass>> deepClonedObject = foobar.DeepClone();
1 голос
/ 22 ноября 2011

Если у вас есть метод Copy, который может дублировать CustomClass объекты:

var newMatrix = oldMatrix
    .Select(subList => subList.Select(custom => Copy(custom)).ToList())
    .ToList();
1 голос
/ 22 ноября 2011

Есть две возможности:

  1. Внедрите интерфейс ICloneable в свой CustomClass, чтобы вы могли клонировать свои объекты.

  2. Если класс можно сериализовать, сериализовать его в поток памяти и десериализовать его оттуда. Это создаст его копию.

Я бы предпочел воспользоваться первой альтернативой, потому что я думаю, что сериализация / десериализация медленнее, чем клонирование через ICloneable.

...