2011-03-07 9 views
0

좋은 아침,이것은 불변의 우수 사례입니까? 가정하자

I 클래스

public class Class 
{ 
    int something; 
    int[] otherThing; 
} 

을하고 난 불변의 유형 Class의 객체를 만들고 싶어. 너무 자주 새로운 객체를 생성 방지하기 위해, 내가 형 Class의 새로운 객체를 생성하는 매우 빈번한 작업이 것이

public Class SomeFunction() 
{ 
    int[] Temp = new int[] { ... }; 

    return new Class(1, Temp); 
} 

을 가정하고 Temp 이후이 너무 나쁘다, 방법 중 더 이상 액세스 할 수 없습니다 생성자 대신

otherThing = new uint[Temp.Length]; 

for (int i = 0; i < Temp.Length; i++) 
{ 
    this.otherThing[i] = Temp[i]; 
} 

this.otherThing = Temp; 

설정?

대단히 감사합니다.

답변

3

이 작업을 수행하는 생성자가 고급 IMO를 전용으로 사용하는 경우. 다른 배열의 내용이 변경되지 않을 것이므로 직접 사용할 수 있습니다. 문제를 일으키지 않고 원하는 경우 클래스의 여러 인스턴스간에 하나의 배열 인스턴스를 공유 할 수도 있습니다.

제공된 배열을 직접 사용하는 공용 생성자는 다른 한편으로는 좋지 않습니다. 그 이후로 불변성을 깨뜨릴 수 있습니다.

0

첫 번째 옵션에서는 항상 새 인스턴스를 얻고 두 번째 옵션에서는 생성 된 모든 클래스가 동일한 배열 (!)을 가리키게됩니다. 따라서 어떤 클래스에서 배열의 내용을 변경하면 다른 모든 클래스가 변경됩니다.

+0

-1. 내가 그 사실을 알고 있다는 사실이 내가 왜 그 질문을 제기하고 있는지 요. 또한 동일한 배열을 가리 키지 않습니다. 메소드는 생성자에 매개 변수로 전달되는 배열을 가리키며, 이는 메소드가 호출 될 때마다 새로 생성됩니다. – Miguel

+0

@Miguel : 아니요. 배열은 참조 유형이므로 패스이며 참조로 저장됩니다. – Euphoric

+0

글쎄, 당신이 100 % 배열이 바뀌지 않는다면 당신이 새로운 배열을 필요로 할 것이라고 말하고 싶습니다. 그러나 그때는 일정하고 매번 전달할 필요가 없습니다. – Geniedesalpages

2

temp의 복사본을 otherThing에 할당하여 otherThing의 변경 사항이 temp으로 변경되지 않도록하는 것이 좋습니다. 이 목적으로 Array.CopyTo 방법을 사용할 수도 있습니다.

또한 어쨌든 배열은 불변의 생각에 반하여 작동하기 때문에 int[] 대신 IEnumerable<int> 또는 IList<int>을 사용해야합니다. Read this blog post by Eric Lippert.

+0

'otherThing'은 비공개 필드입니다. 따라서 필드를 IEnumerable 또는 IList 으로 만들 필요가 없습니다. 필드를 노출 할 때'ReadOnlyCollection '에 래핑하거나 배열을 숨기는 방식으로'GetEnumerator'를 통과시켜야합니다. 그리고 그가 패스 한 배열이 필드에 할당 된 후 변경되지 않는다는 것을 보장 할 수 있기 때문에 복사하지 않고도 안전합니다. – CodesInChaos

+0

이것이 사실이라면 IEnumerable 또는 ReadOnlyCollection 과 같은 안전한 데이터 구조로 동일한 작업을 수행 할 수있는 경우 왜 배열로 시작해야합니다. 그래서 기본적으로 변경 가능한 데이터 구조를 사용하고 프로그래머가 불변으로 취급하는 이유는 무엇입니까?앞으로이 코드를 변경하고 유지 관리하는 다른 개발자는 배열이 불변으로 취급되어야한다고 어떻게 알 수 있습니까? 왜 대신 불변의 순서를 사용하지 않습니까? –

+0

클래스 내부의 코드를 변경하는 사람은 누구나 자신이하는 일을 항상 알고 있다고 가정합니다. 물론 배열이 변경되지 않는다는 것을 문서화해야합니다. 그리고 그 자체로는'IEnumerable '은 단지 하나의 인터페이스이므로 변경할 수 없거나 변경할 수 없습니다. 이는 인터페이스를 백업하는 데 사용하는 컬렉션에 따라 다릅니다. 'ReadOnlyCollection '도 변경할 수 없습니다. 'IList '이 전달되었다는 것을 안다면 여전히 변경할 수 있습니다. – CodesInChaos

관련 문제