2014-11-03 3 views
0

Извините, если заголовок и вопрос не ясны; У меня нет хорошего способа описать это. Но вот оно:Запутывание поведения ParamArray - повторяющиеся массивы как-то связаны?

Так что происходит, что «testMat» каким-то образом связаны друг с другом, и это меняет ценности, даже если я их не переопределяю. Например, если вы запустите этот код ниже, вы увидите, что в функции matSum testResult значения out1 и out2 меняются как изменения (в цикле), о которых я понятия не имею, почему! Их значения не изменяются в testResult1. Откуда такое поведение?

Sub Main() 

    Dim testMat As Double(,) = {{1, 2}, {3, 4}} 

    Dim testResult As Double(,) = matSum(testMat, testMat, testMat) 
    Dim testResult1 As Double(,) = matSum({{1, 2}, {3, 4}}, {{1, 2}, {3, 4}}, {{1, 2}, {3, 4}}) 

End Sub 


Function matSum(ByVal ParamArray args As Double()(,)) As Double(,) 
    'This function sums matrices. It assumes you know how to sum matrices. 

    Dim m, n As Integer 
    Dim out, out1, out2 As Double(,) 
    Dim numArgs As Integer = args.Length 

    out = args(0) 
    out1 = args(1) 
    out2 = args(2) 
    m = out.GetUpperBound(0) 
    n = out.GetUpperBound(1) 

    For v As Integer = 1 To numArgs - 1 
     For i As Integer = 0 To m 
      For j As Integer = 0 To n 
       out(i, j) = out(i, j) + args(v)(i, j) 
      Next 
     Next 
    Next 

    Return out 

End Function 
+1

Array - ссылочный тип, вот почему это происходит. Это не имеет никакого отношения к 'ParamArray'. – MarcinJuraszek

+0

Извините, не могли бы вы немного подробнее? Я думал, что прочитал, что ParamArray был только ByVal? (Или это не то, о чем вы говорите?) – Esteban

+0

С помощью «ByVal» вы не можете изменить личность «args» (например, вы не можете указывать «args» на новый или другой массив), но вы можете изменить его содержимое, т. е. элементы массива. –

ответ

1

ОК, чтобы получить его немного больше контекста.

Array является ссылочным типом, поэтому при его передаче ByVal передаваемая стоимость является ссылкой. Массив не копируется и не клонируется. Ссылка есть. Но он все же указывает на тот же массив в памяти.

Теперь, когда вы вызываете ваш метод здесь.

Dim testResult As Double(,) = matSum(testMat, testMat, testMat) 

out, out1 и out2 имеют одинаковое значение - ссылка на testMat. Изменение значений в этом массиве с использованием любой из этих переменных приведет к изменению одного и того же массива, и вы также увидите его из других ссылок.

+1

Спасибо, я думаю, что получил различие. Это те проблемы, которые вы получаете, когда Matlab является вашим основным «языком». – Esteban