2009-12-02 3 views
0

C#에서 AtomicReference 클래스를 만들려고하고 필드 참조를 보호 된 상태로 유지하려면 get 메서드에서 값을 반환해야합니다.C#을 어떻게 원자 클래스의 필드를 보호하기 위해?

class AtomicReference 
{ 
    private Object _value; 

    public AtomicReference() 
    { 
     _value = new Object(); 
    } 

    public AtomicReference(Object value) 
    { 
     OptimisticSet(value); 
    } 

    public Object CompareAndSet(Object newValue) 
    { 
     return Interlocked.Exchange(ref _value, newValue); 
    } 

    public void OptimisticSet(Object newValue) 
    { 
     do { 
     } while (_value == Interlocked.CompareExchange(ref _value, _value, newValue)); 
    } 

    public Object Get() 
    { 
     // Don't leak the field reference 
     const Object constVal = _value; 
     return constVal; 
    } 
} 

주위에 서투른 방법입니다. 문제는 ... 필드를 읽기 전용으로 설정할 수 없기 때문에 필드를 설정할 수 있어야합니다. 저보다 나은 해결책이 있습니까?

업데이트 : 빠른 답변 주셔서 감사합니다! 단순히 _value를 반환하면 참조가 보호된다는 것이 정당하게 지적되었습니다. 나는 또한 _value를 변이로부터 보호하기를 원한다. _value가 AtomicReference 외부에서 변형되도록 허용하면이 클래스를 만드는 데 필요한 모든 목적을 달성 할 수 없게됩니다.이를 달성 할 수있는 방법이 있습니까?

+1

왜 자바 태그가 있습니까? – SLaks

+0

방금 ​​Java 태그를 꺼 냈습니다 – Suppressingfire

+1

Java 태그는 Java의 AtomicReference와 비슷한 기능을 원합니다. – Kiril

답변

3

시도해도 C# (안전하지 않은 코드 없음) 또는 Java의 필드에 대한 참조를 반환 할 수 없습니다. (나는 객체에 대한 참조를 의미하지는 않습니다)

발신자가 필드에 쓸 수 없으므로 간단하게 return _value;을 쓸 수 있습니다.

+1

발신자가 _value 자체를 변경하여 다른 객체를 참조 할 수는 없지만 호출자가 _value가 참조하는 객체를 변경할 수 없다는 사실이 사실입니까? 예를 들어, object가 실제로 Square 타입 인 경우 호출자는'obj.Side ++ '를 수행 할 수 있습니다. 질문에 대한 나의 이해는 그러한 돌연변이를 피하기를 바란다. –

+1

그렇다면, 그는 운이 없다. 그럴 수 없어요. (값 유형이나 'IClonable'으로 제한하지 않는 한) 그는 대답을 받아 들였으므로 나는 그 사실을 알지 못한다. – SLaks

+0

예 샘플을 다시 읽었는데 참고 문헌에만 신경을 쓰는 것처럼 보입니다. –

2

C#은 변경 가능 개체에 대한 불변의 참조를 허용하는 C++의 const 키워드를 지원하지 않습니다.

요청하는 작업을 수행하는 데는 두 가지 방법 만 있습니다.

  • 반환 할 때마다 개체를 복제 할 수 있습니다. 이것은 clonable 객체에서만 작동하며 매우 느릴 것임을주의하십시오.
  • 값 유형만 지원할 수 있습니다.
+0

고마워! 죄송합니다. 두 개의 개별 아이디어가 실수로 생각났습니다 ... Int32/Int64를 AtomicReference 클래스에 전달하여 AtomicInteger를 사용하는 적절한 방법을 완전히 숨겼습니다. – Kiril