2016-09-02 7 views
-1

코드 안정성 및 코드 가독성/시각적 영향에 대한 내부 사전 인스턴스 (C#)에 대한 참조를 반환하는 세 가지 방법을 고려하고 있습니다.C#을 사용하여 사전 참조를 안전하게 반환했습니다.

다음 세 가지 방법으로 범위를 좁혔지만 더 좋은 제안이 있습니다. 현재 나는 여분의 보일러 판없이 안전의 최상의 균형으로서 # 3을 선호합니다.

1)

은 이제까지 ReadOnlyDictionary 클래스 탈출시키는 내부 사전을 래핑하는 두 번째 ReadOnlyDictionary 인스턴스를 사용

2) IReadOnlyDictionary로 사전 인스턴스를 돌려줍니다,하지만 개주하는 것은있을 수 것 옵션 # 1 또는 # 3만큼 안전하지 않게 수정되었습니다.

3) 복귀 Dictionary.ToImmutableDictionary()는 리턴 된 객체가 내부 사전 불변 도면이다 있도록 이것이 높은 초래 모든 호출에 대한 새로운 복사본을 만들더라도, 포함하는 클래스 탈출 ImmutableDictionary로서 비용, 작은 괜찮은 사전 (광산 있습니다)으로 잘되어야합니다.

private readonly Dictionary<string, string> innerDictionary = new Dictionary<string, string>(); 

    // Only required for Example #1 
    private readonly IReadOnlyDictionary<string, string> readonlyInnerDictionary; 

    public ExampleClass() { 
     // Only required for Example #1 
     readonlyInnerDictionary = new ReadOnlyDictionary<string, string>(innerDictionary); 
    } 

    public IReadOnlyDictionary<string, string> GetExampleOne() { 
     // Requires a second dictionary which is more boiler plate but the object being returned is truly readonly 
     return readonlyInnerDictionary;  
    } 

    public IReadOnlyDictionary<string, string> GetExampleTwo() { 
     // Requires InnerDictionary be defined as Dictionary (Not IDictionary) but doesn't require the second dictionary be defined 
     // which is less boiler plate, but the object returned could be re-cast to it's mutable form meaning it's not truly mutation safe. 
     return innerDictionary; 
    } 

    public ImmutableDictionary<string, string> GetExampleThree() { 
     // Truly immutable object returned, but a new instance is built for every call; fortunately all of my dictionaries are small (containing at most 9 keys) 
     return innerDictionary.ToImmutableDictionary(); 
    } 

답변

0

깔끔하고, 쉽고, 안전합니다. 가장 좋은 수행 방법은 내부적으로 ConcurrentDictionary을 사용하여 스레드 안전성을 보장 (System.Collections.Concurrent) 한 다음 System.Collections.Immutable을 사용하여 dictionary.ToImmutableDictionary()을 호출하여 내부 클래스를 이스케이프 처리하는 사전을 생성하는 것입니다. 인터페이스 서명은 ImmutableDictionary<KeyType, ValueType>입니다.

이것은 가장 뛰어난 솔루션은 아니지만 필자의 경우 12 개 미만의 키가있는 사전과 대부분의 경우 상태를 나타내는 작은 간단한 개체가 걱정되지는 않습니다.

1

옵션 1이 좋습니다. 당신은 IDictionary에 ReadOnlyDictionary를 재조명 할 수 있지만, 변이 할 때 그 예외가 발생합니다 :

void CastingTest() 
     { 
      var dic1 = new Dictionary<string, string>(); 
      dic1.Add("Key", "Value"); 
      var dic2 = new ReadOnlyDictionary<string, string>(dic1); 
      var castedDic = (IDictionary<string, string>)dic2; 
      castedDic.Add("AnotherKey", "Another Value"); //System.NotSupportedException, Collection is read only 
     } 

ReadOnlyDictionary 다른 사전을 만들지 않습니다. 첫 번째 것과 동일한 참조를 가리키며 캡슐화합니다. 그래야하는 경우 :

void AddTest() 
     { 
      var dic1 = new Dictionary<string, string>(); 
      dic1.Add("Key", "Value"); 
      var dic2 = new ReadOnlyDictionary<string, string>(dic1); 
      dic1.Add("Key2", "Value2"); //Now dic2 have 2 values too. 
     } 

내전어를 노출시키지 마십시오. 괜찮을 것입니다.

+0

@Syntax 문제를 해결 했습니까? 원한다면 더 자세한 정보를 공유 할 수 있습니다. –

+0

아더 (Arthur)의 연기로 불편을 끼쳐 드려 죄송합니다. 귀하의 의견은 토론을 진행하는 데 매우 도움이되었지만, 친구와 함께 더 논의한 후에 더 많은 것을 선호하는 또 다른 해결책을 발견했습니다. 관심있는 사람은 내 질문에 대한 답변으로 제공하고 받아 들인 것으로 표시했습니다. – Syntax

+0

아무 문제 없지만, 음, 스레드 안전을 원한다고 명시하지 않았고, 심지어 래핑중인 사전을 노출시키지 않으면 ReadOnlyDictionary는 스레드로부터 안전합니다. –