2009-06-02 2 views
33

나는 이것의 예를 보았지만 조금봤을 때 맹세했지만 그것을 찾을 수는 없다.C#은 get에서 읽기 전용으로 변수를 반환합니다. 세트;

개체에 대한 참조가 있고 GET이 필요한 클래스가 있습니다. 그것을위한 방법. 내 문제는 다른 사람들이 그걸 가지고 바이올린을 할 수 없도록하려는 것입니다. 즉, 내가 읽기 전용 버전을 갖기를 원합니다. (예를 들어, 내 수업에서 변경할 수 있어야합니다.)

감사

+1

얼마나 많은 사람들이 질문을 잘못 이해했는지 놀랍습니다. Jon Skeet과 Anton Gogolev가 올바르게했습니다. –

+1

나는 오해하지 않았다고 생각하지 않았다. - 그래도 아직 투표가 끝났다. - 오 잘. – ChrisF

+0

그것은 트릭 질문이었다. :) –

답변

51

아니,이 일을있는 방법은 없습니다. 예를 들어 List<string>을 반환하면 (변경 불가능하지 않음) 을 호출하면에 항목을 추가 할 수 있습니다.

정상적인 방법은 변경 불가능한 래퍼를 반환하는 것입니다. ReadOnlyCollection<T>.

다른 변경 가능한 유형의 경우 값을 복제하기 전에 복제해야 할 수 있습니다.

변경 불가능한 인터페이스보기 (예 : List<T> 대신 IEnumerable<T>)를 반환해도 발신자가 변경 가능 유형으로 변경하여 변형 될 수 있습니다.

편집 :이 떨어져 다른 어떤에서 참고는 우려의이 종류는 불변의 유형을 쉽게 코드 :

+2

복제를위한 +1 (이미 +1 한 것 제외) –

+2

처음에는 완료 할 수 없다고 말합니다. 클로닝 솔루션에. 또한 어쩌면 복제는 C#의 새로운 아이디어이지만, 예를 들어 C++에서는 오랫동안 사용 해왔다. 또한 엄격하게 복제되지 않습니다. 내부 데이터의 복사본을 생성하고 원래 데이터가 아닌이 복사본을 반환합니다. 복사본은 원본과 동일한 형식 일 필요는 없습니다. – mayu

6

반환 벗겨진 다운 인터페이스에 대한 참조 :

interface IFoo 
    string Bar { get; } 

class ClassWithGet 
    public IFoo GetFoo(...); 
+1

이상적으로는 IFoo의'private' 또는'internal' 구현을 포함하고 있기 때문에 되돌릴 수 없습니다;) – jerryjvl

+0

Hum No, 인터페이스가 내부 또는 개인이면 안됩니다. 액세스 할 수없는 유형의 Public 멤버를 반환 할 수 있어야합니다. "일관성없는 접근성 : 필드 유형 ... 필드보다 접근하기가 쉽지 않습니다." –

3

이 가능하지 않은 추론 할 수 있도록 이유 중 하나입니다. 참조 유형에 접근 자 가져 오기 및 설정 객체에 대한 참조를 가져오고 설정합니다. 비공개 (또는 내부) setter를 사용하여 참조가 변경되는 것을 방지 할 수 있지만 getter에 의해 노출 된 경우 객체 자체에 대한 변경을 방지 할 수는 없습니다.

+0

예 가능합니다. 데이터 복사본을 반환 할 수 있습니다. – mayu

3

개체가 너무 복잡하거나 광범위하지 않은 경우에는 래퍼를 작성하십시오. 예를 들어

:

class A { 
    public string strField = 'string'; 
    public int intField = 10; 
} 

class AWrapper { 
    private A _aObj; 

    public AWrapper(A aobj) { 
     _aObj = A; 
    } 

    public string strField { 
     get { 
      return _aObj.strField; 
     } 
    } 

    public int intField { 
     get { 
      return _aObj.intField; 
     } 
    } 
} 

그래서 지금 당신이 할 모든 그들은 단지 당신이 그들을 볼 수 있도록 무엇을 사용할 수 있도록 클라이언트 코드에게 AWrapper 클래스의 인스턴스를 제공합니다.

기본 클래스가 돌로 설정되지 않은 경우 조금 복잡해지고 확장되지 않을 수 있지만 대부분의 경우 단순한 트릭 일 수 있습니다. 나는이 외관 패턴라고 생각한다 (그러나 = 그 날을 인용하지 않음) 내 간단한 코드 참조) 난 ReadOnlyCollection

에 동의

0

을 :

private List<Device> _devices; 
public readonly System.Collections.ObjectModel.ReadOnlyCollection<Device> Devices 
{ 
get 
{ 
return (_devices.AsReadOnly()); 
} 

}

ReadOnlyCollection를 사용자가 메소드를 호출하여 객체를 수정할 수있는 경우 해당 속성을 추가 할 수 없도록 Add 메소드가 있습니다.지금까지 제가 제대로 질문을 해석하고있어 잘 모르겠어요 답변 주어진 다음

public PropertyName { get; private set; } 

그러나 : 당신이 찾고있는 것처럼

1

귀하의 질문을 읽습니다. 게다가, 나는 누가 존 스키켓에게 질문 할 것인가? :)

+0

할당 할 수 없으므로 읽기 전용 인 참조가 반환되지만 속성은 읽기 전용이 아니기 때문에 계속 편집 할 수 있습니다. – DCShannon

0

나는이 문제에 대해 일정한 방법으로 직면했다.

public CategoryViewModel 
{ 
    private Category { get; } 

} 

는 사실, 내가 읽기 전용 다른 클래스로 내보낼 수 원하는 : 은 내가 개인 읽기 전용 원하는 속성 카테고리를 가지고 CategoryViewModel 클래스를 가지고있다. 그러나 나는 그런 일을 할 수 없다. 필자의 경우 (다른 사람들에게 도움이 될 수도 있음) 저장소에 추가하고 싶습니다.

categoryViewModel.ApplyAction(_repository, (r, c) => r.MarkForInsertOrUpdate(c)); 
: 나는 그런 일을 할 수 있고, 다른 곳에서, 그와 같이

public void ApplyAction(ICategoryRepository repo, Action<ICategoryRepository, Category> action) 
{ 
    action(repo, Category); 
} 

: 내가 찾은 유일한 방법은 PARAM 1과 저장소와 기능, PARAM이 같은 행동을하는 것입니다

다른 사람이 특정 사례에 대해서만 속성을 노출하고 관리 할 수 ​​있도록 도와줍니다.

관련 문제