2010-12-16 5 views
0

내 프로그램에서 개체 복사본을 만드는 대신 포인터를 할당하기로 결정했는데 이유가 확실하지 않습니다.VB.net 3.5 할당 연산자가 복사 대신 포인터를 할당합니까?

Public Class Foo 
     Private myFooData As New List(Of FooData) 

     Public Sub New(ByVal newFooData As List(Of FooData)) 
      myFooData = newFooData 
     End Sub 

     Public Property FooValues() As List(Of FooData) 
      Get 
       Return myFooData 
      End Get 
      Set(ByVal value As List(Of FooData)) 
        myFooData = value 
      End Set 
     End Property 
    End Class 

그리고이 같이 사용되는 : 나는 이런 식으로 뭔가가

Public Sub Dosomething() 
     Dim mainFoo as new Foo 

     For x = 1 to 10 
      mainFoo.FooValues(x) = New FooData 
     Next 

     Dim originalFoo as new Foo 
     originalFoo.FooValues = mainFoo.FooValues.Take(3).ToList 

     Dim newFoo as new Foo 
     newFoo.FooValues = originalFoo.FooValues 

     newFoo.FooValues(1) += 1 
    End Sub 

매우 단순화를하지만, 기본적으로 내가 뭘하는지. 따라서 어떤 이유로 오늘 newFoo.FooValues에서 item을 변경하면 originalFoo.FooValues도 변경되고 mainFoo는 변경되지 않습니다. 전체 개체를 할당하려고 시도했지만 동일한 결과가 나타납니다. 이것이 일어날 수있는 이유와 해결 방법에 대한 아이디어가 있습니까?

답변

2

이렇게하면 .Net의 할당이 작동하는 방식입니다.

두 번째 스 니펫 중간에 .ToList()을 호출하면 코드가 집합을 반복하여 완전히 새로운 목록으로 복사합니다. 이것이 mainFoo 객체가 "보호 된"이유입니다. — 새 인스턴스를 만들었습니다. 복사되는 FooData 항목 자체가 객체에 대한 참조 인 경우 (힌트 : 아마도), 참조 만 복사됩니다. 유일한 예외는 문자열 및 값 유형 (프리미티브 및 구조) 또는 직접 코드화하는 경우입니다.

그것은 일반적으로 목록의 속성이 속성 읽기 전용으로 만들기위한 좋은 생각이 여전히 당신이 당신의 마음의 콘텐츠에 대한 목록을 조작 할 수있게된다

Public Property FooValues() As List(Of FooData) 
    Get 
     Return myFooData 
    End Get 
End Property 

,하지만 완전히 아래에서 목록 인스턴스를 전환하지 못하도록 클래스. 클래스에서 속성으로 노출 된 다른 복합 유형에 대해서도 마찬가지입니다.

당신이하고 싶지 않은 것은 이것을 클래스 대신 구조로 바꾸는 것입니다. 이것은 처음에는 원하는 것을하는 것처럼 보일 수 있지만 나중에 다른 문제가 발생할 수 있습니다.

+0

FooData는 두 개의 setable 속성을 갖는 또 다른 클래스입니다. 둘 다 소수입니다. 나는 원래 FooValues를 새로운 FooValues와 속성 집합에도 할당 할 때 .ToList()를 사용해 보았습니다.하지만 여전히 동일하게 작동합니다. 그래서 당신은 선택의 일종을 취해야한다고 가정합니다. 그것을 사용하여 사본을 만듭니다. – Loscas

+0

@Loscas 복사를 자동으로 생성 할 수있는 방법이 없습니다. 데이터 복사가 비효율적이며 디자인이 좋지 않습니다 (부실 데이터로 작업하는 것을 촉진합니다). –

1

Foo.FooValues을 사용하는 경우 Foo에 내부적으로 사용되는 List(Of FooData)에 대한 참조를 할당하고 값을 지정하지 마십시오!

은의이 단계
Dim mainFoo as new Foo 

mainFoo 지금 자신의 백업 목록이

을 생각해 보자.
originalFoo.FooValues = mainFoo.FooValues.Take(3).ToList 

originalFoo

mainFoo의 값의 일부를 저장하는 새로운 배면에서 할당 얻는다.

자신의 백업 목록을하는 데 사용
newFoo.FooValues = originalFoo.FooValues 

newFoo,하지만 지금, 그것은 하나 개의 originalFoo 사용을 사용합니다. 똑같은 하나 (포인터에 의해)와 사본 없음.

그러므로 newFoo을 변경하면 originalFoo이 변경되지만 자체 목록이있는 mainFoo은 변경되지 않습니다.

결국 달성하고자하는 것이 무엇인지 알 수 없기 때문에 코드를 수정하는 방법을 알 수는 없지만 알 수 있듯이 일부 백업 목록에 액세스 가능하도록 지정하는 것은 좋은 생각이 아닙니다.

따라서 목록 을 유지하려면개인을 할당하고 색인 액세스 권한을 부여하십시오.

+1

+1. 하지만 VB에서 참조 유형에 대입하면 대입 연산자가 항상 포인터를 할당합니다. – pipTheGeek

+0

속성의 설정 값이 byVal이라하더라도 byRef로 취급하고 있습니까? – Loscas

+1

@Loscas - .Net에서 변수는 대부분 참조 용입니다. 모든 ByVal은 참조 자체가 값으로 복사된다는 것을 의미합니다. 이 점이 왜 더 좋은지에 대해서는 많은 이유가 있습니다. –

관련 문제