2014-11-29 2 views
1

내 programm에 3 차원 배열이 있습니다. 나는 값을 디버그하고 싶고이 배열을 다른 배열에 넣는다. 차이점을 찾고 싶다. 그 후참조없이 다차원 배열을 올바르게 복제하는 방법은 무엇입니까?

Weights weights = new Weights(); // init inside 
List<Weights> weightsDebug = new List<Weigts>(); 
weightsDebug.Add(weights); // I'd put first weigths into the list 
for(int i = 0; i < 100; i++) { 
    // do some bad things with weights; 
    weightsDebug.Add(weights); 
} 

, 내가 weigthsDebug의 모든 99 개 요소의 무게에 같은 값을 가지고 것 :

나는이 시도했다. 나는 디버깅을 시도했고, 깨달았습니다. weigts 배열이 변경되고 있습니다. 나는 그 문제가 참조 (링크에 의해, 가치에 의해 복제되지 않음)에 있다는 것을 이해했다. - 모든 것은 weightsDebug 배열 요소가 메인 루프의 weights과 연결되어있다.

나는 조금 봤 거든 1 차원 배열을 복사하는 방법을 몇 가지 발견. 다음 I'tried :

Weights weights = new Weights(); // init inside 
List<Weights> weightsDebug = new List<Weigts>(); 
weightsDebug.Add(weights); // I'd put first weigths into the list 
for(int i = 0; i < 100; i++) { 
    // do some bad things with weights; 
    Weights weightsClone = weights.Clone(); 
    weightsDebug.Add(weightsClone); 
} 

그리고 난 아직도 얻고 마지막에 값을 변경 : 복사 가중치 때

double[][][] values; 
public Weights Clone() { 
    Weights clone = new Weights(); 
    clone.values = (double[][][]) this.values.Clone(); 
    return clone; 
} 

public Weights() 
{ 
    Console.WriteLine("Constructor WITHOUT arguments fired"); 
} 

지금 내가 이렇게 오전 :

내 무게 클래스에 복제 방법을 추가 전체 디버그 배열. 어떻게 해결할 수 있습니까?

답변

1

여기서 문제는 단일 개체 만있는 진정한 다차원 배열이 없다는 것입니다. 객체가 실제로 배열 배열 인 배열의 "들쭉날쭉 한"다차원 배열이 있습니다.

clone.values = new double[values.Length][][]; 

for (int i = 0; i < values.Length; i++) 
{ 
    clone.values[i] = new double[values[i].Length][]; 

    for (int j = 0; j < values[i].Length; j++) 
    { 
     clone.values[i][j] = (double[])values[i][j].Clone(); 
    } 
} 
2

당신이 정말 여기 찾고있는 것이 아니라 당신이 구현하고있는 현재의 얕은 복제보다 깊은 복제입니다 :이 개체를 복제, 당신은 더 많은 일을 할 필요가 있다는 것을 의미한다.

오래전에 우리는 클래스 Serializable을 만들면 .Net serialization 클래스를 사용하여 모든 객체의 딥 클론을 빠르고 쉽게 만들고 올바르게 만들 수 있음을 알았습니다.

/// <summary> 
    /// This method clones all of the items and serializable properties of the current collection by 
    /// serializing the current object to memory, then deserializing it as a new object. This will 
    /// ensure that all references are cleaned up. 
    /// </summary> 
    /// <returns></returns> 
    /// <remarks></remarks> 
    public T CreateSerializedCopy<T>(T oRecordToCopy) 
    { 
     // Exceptions are handled by the caller 

     if (oRecordToCopy == null) 
     { 
      return default(T); 
     } 

     if (!oRecordToCopy.GetType().IsSerializable) 
     { 
      throw new ArgumentException(oRecordToCopy.GetType().ToString() + " is not serializable"); 
     } 

     var oFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter(); 

     using (var oStream = new MemoryStream()) 
     { 
      oFormatter.Serialize(oStream, oRecordToCopy); 
      oStream.Position = 0; 
      return (T)oFormatter.Deserialize(oStream); 
     } 
    } 

먼저이 사용하는 클래스가 직렬화 속성 태그가 가중치를 보장하기 위해 : 여기

우리가이 깊은 복제에 사용하는 방법입니다 (또한 DataContractSerializer를 사용 실버 변화가있다)

[Serializable] 
public class Weights 

은 그런 다음 필요에 복제 할 수 있습니다 :

 var weights = new List<Weights>(); 
     weights.Add(new Weights()); 

     var debugWeights = CreateSerializedCopy<List<Weights>>(weights); 

     if (debugWeights[0] == weights[0]) 
     { 
      System.Diagnostics.Debug.WriteLine("Did not serialize correctly"); 
     } 
+0

솔직히, USI 단순한 배열을 복사하는 것 같은 경량의 필요성을 해결하기위한 직렬화와 같은 무거운 가중치 기능은 과도한 과장입니다. 다른 시나리오를위한 훌륭한 범용 솔루션이지만 CPU 및 메모리 리소스 낭비 일뿐입니다. –

+0

@PeterDuniho :이 문제는 종종 개발자를 모서리에 넣고 심각한 구현 문제를 만들어내는 문제입니다. 예를 들어 다른 개발자가 길 아래 클래스에 다른 속성을 추가했지만 복제되지 않았다는 것을 알지 못하면 어떻게됩니까? 나는 이것이 여러 번 일어나는 것을 보았고 고객을 위해 실제 CPU 사용량이 솔루션에서 제공하는 안정성 이상의 가치가 있다는 것을 보여주었습니다. CPU 사용량이 그다지 큰 관심사가 아니라면 복제가 처음부터 사용되어서는 안됩니다. –

관련 문제