2009-10-23 3 views
1

Я использую класс BigNumDesc, который представляет число. У меня есть зубчатый массив этих чисел, которые представляют собой матрицу. я сначала объявить эту матрицу следующим образом:Глубокие типы ссылок копирования

BigNumDec[][] matrix = new BigNumDec[][] { 
     new BigNumDec[] { 1, 2 }, 
     new BigNumDec[] { 3, 4 } 
    }; 

Теперь, у меня есть метод, который я хочу назвать:

static BigNumDec[][] GetStrictlyUpperTriangle(BigNumDec[][] matrix) 
{ 
    BigNumDec[][] newMatrix = new BigNumDec[matrix.Length][]; 
    matrix.CopyTo(newMatrix, 0); 
    return null; 
} 

У меня есть брейк-пойнт в последней строке. Если в окне просмотра я беру любой элемент матрицы и меняю его, он изменит слишком newMatrix, так как все BigNumDec являются ссылочными типами (плохое дизайнерское решение от создателя этого?). Как я могу это сделать? Мне нужно внести изменения в newMatrix, поэтому я должен сначала скопировать его из матрицы.

Редактировать: Пробовал то же самое теперь с ints, но это происходит точно так же. Я бы это не случилось с типами ценностей?

BigNumDec является неизменным.

ответ

3

Причина, по которой все еще происходит с типами значений, заключается в том, что вы используете массив массивов. Вы несетечно копируете «внешний» массив, который просто копирует ссылки на два «внутренних» массива.

Вы не указали, является ли BigNumDec неизменным или нет (я бы так надеялся), но если это так, вы должны быть в порядке, если вы просто глубоко скопируете массив. В качестве альтернативы, вы можете использовать прямоугольный массив [,] вместо массива с зазубриванием [][]? Если это так, достаточно простой копии. Имейте в виду последствия производительности с прямоугольными массивами, заметьте - стоит проверить это, чтобы увидеть, будет ли это проблемой для вас. Вы получаете лучшую локальность ссылок, но фактический доступ к массиву не так быстр.

+0

С простой для этого хорошо работает с ints. Будет ли это хорошо работать с BigNumDec? Я бы сказал, нет. –

+0

Кажется, что работает. Теперь я смущен. –

+0

Не могли бы вы объяснить, почему быть неизменным или нет, если это возможно, имеет значение здесь? Когда он обнаруживает, что я хочу изменить значение, он создает новый за кулисами? –

1

Проблема заключается в вашей инициализации массива BigNumDec, вы создаете одномерный массив объектов BigNumDec. [0] = {1, 2}, [1] = {3. 4}. Затем вы эффективно копируете ссылки на эти объекты, а не на их содержимое, поэтому значения продолжают меняться.

Изменить инициализацию на:

BigNumDec[,] matrix = new BigNumDec[,] { 
    { 1, 2 }, 
    { 3, 4 } 
}; 
1

Если ваши объекты Сериализуемые вы можете осуществить глубокую копию, используя сериализацию. Это не очень эффективно (по производительности), но это просто.

public BigNumDec[][] CopyUsingSerialization(BigNumDec[][] original) 
{ 
    var binaryFormatter = new BinaryFormatter(); 
    var serializationStream = new MemoryStream(); 
    binaryFormatter.Serialize(serializationStream, original); 
    serializationStream.Position = 0; 
    var copy = (BigNumDec[][])binaryFormatter.Deserialize(serializationStream); 
    return copy; 
} 

Вы должны объявить BigNumDec, как [Serializable]:

[Serializable] 
public class BigNumDec 
{ 
    //class content 
} 

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

Смежные вопросы