2016-12-22 1 views
4

개인 클래스 멤버 (myData 유형의 currentData)가 포함 된 클래스 (myClass)가 있습니다. 그 회원을 "가져올"수있는 속성 (CurrentData) 있습니다. 사용자가 currentData에서 함수를 호출 할 수 있지만 외부 참조를받지 못하도록하고 싶습니다. 예 :C# - 클래스 멤버를 참조하는 것을 방지하려면 어떻게해야합니까?

myClass a = new myClass(); 

// This is OK 
a.CurrentData.somefunc(); 

// This is what I dont want 
myData m = new myData(); 
m = a.CurrentData; 
// ... some time passes here... 
m.someFunc(); 

나는 동일한 객체를 참조합니다. 내부 멤버가 예기치 않게 바뀔 수 있으므로 내 클래스 외부에서 내부 멤버로 참조가 유지되는 것을 원하지 않습니다.

이것이 가능합니까? 나는 C#에서 멀리 있었으므로 오랫동안 나는 그것이 어떻게 작동하는지 기억할 수 없다!

+0

슬프게도 불가능하지만 – Steve

답변

9

a.CurrentData.somefunc(); 

법적 만드는 방법하지만

m = a.CurrentData; 

불법이 아니다. a.CurrentData.somefunc();은 본질적으로 인라인 참조를 a.CurrentData으로 반환 한 다음 해당 참조에서 somefunc()을 호출합니다.

public void DoSomeFuncWithCurrentData() 
{ 
    this.currentData.someFunc(); 
} 

myClass a = new myClass(); 

a.DoSomeFuncWithCurrentData(); 
1

당신은 외부 참조를 복용하지 못하도록 할 수 없습니다 당신이 내부 객체에 대한 참조를 방지하려면

다음은 포함 된 객체에 통과 포함하는 클래스에 메소드를 추가해야합니다 - 외부 참조가 당신 안에 무엇을 변경할 가능성이 없을 것입니다 그런 식으로

  • 불변 내면의 개체 확인 : 개체에,하지만 당신은 두 가지 중 하나는 관련이없는 이러한 참조를 만들기 위해 할 수있는 r 개체. .NET 라이브러리가 문자열로 수행 한 작업입니다.
  • 방어 복사본을 반환하십시오. 이렇게하면 외부 수정이 허용되지만 대상 복사본에 이러한 수정이 적용됩니다.

또 다른 가능성은 클래스를 구조체로 만드는 것이며,이 경우 참조를 전혀 만들 수 없습니다. 값 유형을 사용하면 다른 의미가 있기 때문에이 작업을 신중하게 수행해야합니다.

+0

감사합니다. 나는이 질문에 대한 답을 알고 있었지만 그것이 그렇게 좋지 않았 으면 좋겠다고 생각했다. –

3

참조를 "금지"하는 직접적인 방법은 없습니다.

그러나, 몇 가지 가능한 해결 방법이 있습니다 :

  • 프록시 방법 만들기 : 전혀 CurrentData 재산에 대한 공용 액세스를 허용하지 마십시오. CurrentData 호출 할 수있는 모든 방법에 프록시 방법을 만들기 :

    myClass a = new myClass(); 
    a.SomeFuncOnCurrentData(); 
    

    그런 식으로 당신은 외부 클래스의 내부 동작에 노출시키지 마십시오. 단점은 많은 상용구 코드를 작성해야한다는 것입니다 (또는 상용구 코드를 작성하는 타사 도구를 사용해야합니다).

  • 반환 사본보기 : GetCurrentData 방법으로 CurrentData 속성 바꾸기 모든 호출에 내부 객체의 새 복사본을 반환합니다. 이렇게하면 사용자는 원하는 경우 "이전"데이터를 조작 할 수 있고 사용자 개체는 내부 개체와 연결이 끊어집니다.

  • 내부 개체를 바꾸고 이전 개체 그대로 그대로 두십시오. : MyData을 변경 불가능한 클래스로 지정하십시오. CurrentData이 변경되면 MyData를 수정하지 말고 대신 새 MyData 객체를 만듭니다. 이것은 이전의 점 (사본을 리턴)과 동일한 효과를 가지지 만, 각 호출에서 사본을 작성할 필요가없는 특성을 계속 사용할 수 있습니다. CurrentData 변경은 다음과 같이 수행 : 이전 내부 객체 무효화

    • 내부적 MyData의 새로운 인스턴스를 사용을
    • someFunc 발생 이전 인스턴스에 대한 플래그를 설정할 ObjectExpiredException을 던집니다.
+0

또 다른 옵션은 객체 자체 대신 래퍼 객체를 반환하는 것입니다 – Brandon

1

이 정상이면 :

a.CurrentData.somefunc(); 

을하지만이 확인되지 않습니다 :

이 syntacticaly (즉, 정적) 다음
var currentData = a.CurrentData; 
currentData.someFunc(); 

당신이에 대한 참조의 소비를 금지 할 수 미래의 임의의 시간. 가장 좋은 방법은이 요구 사항을 포함하는 클래스 myClass에 구현하는 것입니다. 메서드가 표면화 된 경우 myClass의 메서드로 someFunc()을 사용하면 myClass에 대한 참조가있을 때만 암시 적으로 (내부) 함수 호출을 허용합니다.

또한 이것이 좋은 해결책 인 경우 CurrentData 속성을 제거해야합니다. 이는 개인 영역을 게시하고 있기 때문입니다. myClass의 방법으로 CurrentData에서 노출해야하는 모든 방법을 전파하십시오 (myClass).

관련 문제