.NET에 사용 가능한 읽기 전용 일반 사전이 있습니까?


186

읽기 전용 속성에서 사전에 대한 참조를 반환합니다. 소비자가 내 데이터를 변경하지 못하게하려면 어떻게합니까? 이것이 있다면 IList나는 단순히 그것을 반환 할 수 AsReadOnly있습니다. 사전으로 할 수있는 일이 있습니까?

Private _mydictionary As Dictionary(Of String, String)
Public ReadOnly Property MyDictionary() As Dictionary(Of String, String)
    Get
        Return _mydictionary
    End Get
End Property

4
이를 수행하는 방법이 있거나 그렇지 않으면 IDictionary에 IsReadOnly 속성이 없을 것입니다 ... ( msdn.microsoft.com/en-us/library/bb338949.aspx )
Powerlord

2
불변성의 많은 개념적 이점은 런타임을 강제하지 않고 얻을 수 있습니다. 이 프로젝트가 개인 프로젝트 인 경우 훈련 된 비공식적 인 방법을 고려하십시오. 소비자에게 데이터를 제공해야하는 경우 딥 카피를 진지하게 고려해야합니다. 불변 콜렉션에 1) 콜렉션에 대한 불변 참조가 필요하다는 것을 고려할 때 2) 시퀀스 자체 변경 방지 및 3) 콜렉션 항목의 특성 수정 금지 및 이들 중 일부가 리플렉션에 의해 위반 될 수 있음을 고려하면 런타임 적용은 다음과 같습니다. 실용적이지 않습니다.
Sprague


2
이 또한 지금 NuGet을 통해 마이크로 소프트 불변의 컬렉션은 msdn.microsoft.com/en-us/library/dn385366%28v=vs.110%29.aspx
VoteCoffee

답변:


156

다음은 사전을 감싸는 간단한 구현입니다.

public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    private readonly IDictionary<TKey, TValue> _dictionary;

    public ReadOnlyDictionary()
    {
        _dictionary = new Dictionary<TKey, TValue>();
    }

    public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
    {
        _dictionary = dictionary;
    }

    #region IDictionary<TKey,TValue> Members

    void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
    {
        throw ReadOnlyException();
    }

    public bool ContainsKey(TKey key)
    {
        return _dictionary.ContainsKey(key);
    }

    public ICollection<TKey> Keys
    {
        get { return _dictionary.Keys; }
    }

    bool IDictionary<TKey, TValue>.Remove(TKey key)
    {
        throw ReadOnlyException();
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        return _dictionary.TryGetValue(key, out value);
    }

    public ICollection<TValue> Values
    {
        get { return _dictionary.Values; }
    }

    public TValue this[TKey key]
    {
        get
        {
            return _dictionary[key];
        }
    }

    TValue IDictionary<TKey, TValue>.this[TKey key]
    {
        get
        {
            return this[key];
        }
        set
        {
            throw ReadOnlyException();
        }
    }

    #endregion

    #region ICollection<KeyValuePair<TKey,TValue>> Members

    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
    {
        throw ReadOnlyException();
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Clear()
    {
        throw ReadOnlyException();
    }

    public bool Contains(KeyValuePair<TKey, TValue> item)
    {
        return _dictionary.Contains(item);
    }

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        _dictionary.CopyTo(array, arrayIndex);
    }

    public int Count
    {
        get { return _dictionary.Count; }
    }

    public bool IsReadOnly
    {
        get { return true; }
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
    {
        throw ReadOnlyException();
    }

    #endregion

    #region IEnumerable<KeyValuePair<TKey,TValue>> Members

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return _dictionary.GetEnumerator();
    }

    #endregion

    #region IEnumerable Members

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    #endregion

    private static Exception ReadOnlyException()
    {
        return new NotSupportedException("This dictionary is read-only");
    }
}

11
링크가 아닌 완전한 코드를 게시 한 +1이지만 궁금합니다. ReadOnlyDictionary에서 빈 생성자의 요점은 무엇입니까? :-)
Samuel Neff

20
그 생성자를 조심하십시오. 전달 된 사전의 참조 사본을 수행하는 경우 외부 코드 조각이 "읽기 전용"사전을 수정할 수 있습니다. 생성자는 인수에 대한 완전하고 깊은 사본을 작성해야합니다.
askheaves

25
@askheaves : 좋은 관찰이지만 실제로 읽기 전용 유형의 원래 참조를 사용하는 것이 유용합니다. 개인 변수를 원래 변수로 유지하고 외부 소비자를 위해 수정하십시오. 예를 들어, ReadOnlyObservableCollection 또는 기본 제공되는 ReadOnlyCollection 개체를 확인하십시오. Thomas는 .Net 프레임 워크 고유의 것과 동일한 기능을 제공했습니다. 고마워 토마스! +1
Matt DeKrey

13
@ user420667 : 구현 방식은 "읽기 전용이 아닌 사전의 읽기 전용보기"입니다. 다른 코드는 원래 사전의 내용을 변경할 수 있으며 이러한 변경 사항은 읽기 전용 사전에 반영됩니다. 달성하고자하는 바에 따라 원하는 행동 일 수도 있고 아닐 수도 있습니다.
Thomas Levesque

6
@Thomas : .NET BCL의 ReadOnlyCollection과 동일합니다. 변경 가능한 콜렉션에 대한 읽기 전용보기입니다. ReadOnly는 불변성을 의미하지 않으며 불변성을 기 대해서는 안됩니다.
Jeff Yates

229

.NET 4.5

.NET Framework 4.5 BCL에 ReadOnlyDictionary<TKey, TValue>( source )가 도입되었습니다 .

.NET Framework 4.5 BCL에는 AsReadOnly사전 용이 포함되어 있지 않으므로 원하는 경우 직접 작성해야합니다. 다음과 같을 것입니다. 단순성은 아마도 .NET 4.5의 우선 순위가 아닌 이유를 강조합니다.

public static ReadOnlyDictionary<TKey, TValue> AsReadOnly<TKey, TValue>(
    this IDictionary<TKey, TValue> dictionary)
{
    return new ReadOnlyDictionary<TKey, TValue>(dictionary);
}

.NET 4.0 이하

.NET 4.5 이전 Dictionary<TKey, TValue>에는 ReadOnlyCollection을 감싸는 것처럼 List 를 감싸는 .NET Framework 클래스가 없습니다 . 그러나 하나를 만드는 것은 어렵지 않습니다.

다음은 예 입니다. Google이 ReadOnlyDictionary를 사용하는 경우 많은 다른 것들이 있습니다 .


7
그들이 AsReadOnly()평소에 방법 을 만드는 것을 기억 한 것처럼 보이지 않으므로 Dictionary<,>얼마나 많은 사람들이 그들의 새로운 유형을 발견하게 될지 궁금합니다. 그러나이 스택 오버 플로우 스레드가 도움이 될 것입니다.
Jeppe Stig Nielsen

@Jeppe : 기억과 관련이있는 것 같아요. 모든 기능은 비용이 많이 들며 AsReadOnly가 우선 순위 목록에서 높은 것으로 의심됩니다. 특히 작성하기가 쉽기 때문입니다.
Jeff Yates

1
이것은 단순히 래퍼입니다. 기본 사전 (생성자에 전달 된 사전)을 변경해도 여전히 읽기 전용 사전이 변경됩니다. 또한 참조 stackoverflow.com/questions/139592/...
TrueWill

1
@JeffYates 얼마나 간단한 지 생각해 보면 글쓰기에 시간을 소비할지 여부를 결정하는 것보다 시간이 덜 걸렸을 것입니다. 이 때문에 내 베팅은 "그들은 잊어 버렸습니다".
Dan Bechard

TrueWill에서 언급했듯이 기본 사전은 여전히 ​​변경 될 수 있습니다. 불변성을 원한다면 원래 사전의 복제본을 생성자에 전달하는 것을 고려할 수도 있습니다 (키와 값 유형도 불변이라고 가정).
user420667

19

최근 BUILD 컨퍼런스 에서 .NET 4.5 이후 인터페이스 System.Collections.Generic.IReadOnlyDictionary<TKey,TValue>가 포함 되었다고 발표 되었습니다. 증명은 여기 (Mono)와 여기 (Microsoft)입니다.)

ReadOnlyDictionary포함되어 있는지 확실하지 않지만 적어도 인터페이스를 사용하면 공식 .NET 일반 인터페이스를 제공하는 구현을 만드는 것이 어렵지 않아야합니다. :)


5
ReadOnlyDictionary<TKey, TValue>(닷넷 4.5) - msdn.microsoft.com/en-us/library/gg712875.aspx
myermian

18

간단한 래퍼를 사용하십시오. IDictionary를 구현하지 않으므로 런타임에 사전을 변경하는 사전 메서드에 대해 예외를 throw하지 않아도됩니다. 변경 방법은 단순히 존재하지 않습니다. IReadOnlyDictionary라는 자체 인터페이스를 만들었습니다.

public interface IReadOnlyDictionary<TKey, TValue> : IEnumerable
{
    bool ContainsKey(TKey key);
    ICollection<TKey> Keys { get; }
    ICollection<TValue> Values { get; }
    int Count { get; }
    bool TryGetValue(TKey key, out TValue value);
    TValue this[TKey key] { get; }
    bool Contains(KeyValuePair<TKey, TValue> item);
    void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex);
    IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator();
}

public class ReadOnlyDictionary<TKey, TValue> : IReadOnlyDictionary<TKey, TValue>
{
    readonly IDictionary<TKey, TValue> _dictionary;
    public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
    {
        _dictionary = dictionary;
    }
    public bool ContainsKey(TKey key) { return _dictionary.ContainsKey(key); }
    public ICollection<TKey> Keys { get { return _dictionary.Keys; } }
    public bool TryGetValue(TKey key, out TValue value) { return _dictionary.TryGetValue(key, out value); }
    public ICollection<TValue> Values { get { return _dictionary.Values; } }
    public TValue this[TKey key] { get { return _dictionary[key]; } }
    public bool Contains(KeyValuePair<TKey, TValue> item) { return _dictionary.Contains(item); }
    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { _dictionary.CopyTo(array, arrayIndex); }
    public int Count { get { return _dictionary.Count; } }
    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return _dictionary.GetEnumerator(); }
    IEnumerator IEnumerable.GetEnumerator() { return _dictionary.GetEnumerator(); }
}

4
IDictionary계약을 위반하지 않은 경우 +1 OOP 관점 IDictionary에서 상속 하는 것이 더 정확하다고 생각합니다 IReadOnlyDictionary.
Sam

@ Sam Agreed, 그리고 우리가 되돌아 갈 수 있다면 IDictionary(current IReadOnlyDictionary) 및 IMutableDictionary( current ) 를 갖는 것이 가장 좋고 정확하다고 생각합니다 IDictionary.
MasterMastic

1
@MasterMastic 그것은 기괴한 제안입니다. 불변의 컬렉션이 사용자가 기본적으로 기대하는 것과 반대되는 가정에 의존하는 다른 내장 클래스는 생각 나지 않습니다.
Dan Bechard 18시 37 분

11

isReadOnly의상의 IDictionary<TKey,TValue>로부터 상속된다 ICollection<T>( IDictionary<TKey,TValue>연장 ICollection<T>같이 ICollection<KeyValuePair<TKey,TValue>>). 어떤 식 으로든 사용되거나 구현되지 않으며 실제로 연관된 ICollection<T>멤버 를 명시 적으로 구현하여 "숨겨져"있습니다 .

문제를 해결하기 위해 볼 수있는 방법은 적어도 3 가지가 있습니다.

  1. IDictionary<TKey, TValue>제안 된대로 사용자 정의 읽기 전용을 구현하고 내부 사전에 랩 / 위임
  2. ICollection<KeyValuePair<TKey, TValue>>세트를 읽기 전용으로 또는 IEnumerable<KeyValuePair<TKey, TValue>>값 사용에 따라 반환
  3. 복사 생성자를 사용하여 사전을 복제하고 사본 .ctor(IDictionary<TKey, TValue>)을 리턴하십시오. 사용자가 원하는대로 자유롭게 사용할 수 있으며 소스 사전을 호스트하는 오브젝트의 상태에 영향을 미치지 않습니다. 복제중인 사전에 참조 유형 (예제에 표시된 문자열이 아님)이 포함 된 경우 "수동으로"복사를 수행하고 참조 유형도 복제해야합니다.

여담으로; 컬렉션을 노출 할 때 가능한 가장 작은 인터페이스를 노출하는 것을 목표로합니다. 예제의 경우 유형이 노출하는 공개 계약을 위반하지 않고 기본 구현을 변경할 수 있으므로 IDictionary 여야합니다.


8

읽기 전용 사전은 어느 정도 대체 될 수 있습니다 Func<TKey, TValue>.-검색을 수행하는 사람들 만 원할 경우 일반적으로 API에서이를 사용합니다. 간단하고, 특히 원하는 경우 백엔드를 교체하는 것이 간단합니다. 그러나 키 목록은 제공하지 않습니다. 중요한 것은 당신이하는 일에 달려 있습니다.


4

아니요,하지만 쉽게 롤업 할 수 있습니다. IDictionary는 IsReadOnly 속성을 정의합니다. 사전을 포장하고 적절한 메소드에서 NotSupportedException을 던지기 만하면됩니다.


3

BCL에는 없습니다. 그러나 BCL Extras 프로젝트 에 ReadOnlyDictionary (ImmorableMap이라는 이름)를 게시했습니다.

완전 불변의 딕셔너리 일뿐만 아니라, IDictionary를 구현하고 IDictionary가 사용되는 모든 곳에서 사용할 수있는 프록시 객체 생성을 지원합니다. 변경 API 중 하나가 호출 될 때마다 예외가 발생합니다.

void Example() { 
  var map = ImmutableMap.Create<int,string>();
  map = map.Add(42,"foobar");
  IDictionary<int,string> dictionary = CollectionUtility.ToIDictionary(map);
}

9
ImmutableMap은 균형 트리로 구현됩니다. .NET에서 사람들은 일반적으로 "사전"이 해싱을 통해 구현되고 이에 상응하는 복잡한 속성을 표시하기를 기대하므로 ImmutableMap을 "사전"으로 승격시키는 데주의를 기울여야 할 수 있습니다.
Glenn Slayden

code.msdn.com 사이트가 사용되지 않는 것으로 보입니다. BCLextras 이제 여기 github.com/scottwis/tiny/tree/master/third-party/BclExtras
BozoJoe

1

사전의 부분 구현 만 구현하고 모든 추가 / 제거 / 설정 기능을 숨기는 클래스를 작성할 수 있습니다.

외부 클래스가 모든 요청을 전달하는 사전을 내부적으로 사용하십시오.

그러나 사전에 참조 유형이있을 수 있으므로 사용자가 사전이 보유한 클래스의 값을 설정하지 못하게 할 방법이 없습니다 (클래스 자체가 읽기 전용이 아닌 경우).


1

나는 그것을하는 쉬운 방법이 없다고 생각합니다 ... 사전이 커스텀 클래스의 일부라면 인덱서를 사용하여 달성 할 수 있습니다.

public class MyClass
{
  private Dictionary<string, string> _myDictionary;

  public string this[string index]
  {
    get { return _myDictionary[index]; }
  }
}

인덱서뿐만 아니라 전체 사전을 노출 할 수 있어야합니다.
Rob Sobers

이것은 매우 좋은 해결책처럼 보입니다. 그러나 MyClass 클래스의 클라이언트는 사전을 통해 반복하기 위해 사전에 대해 더 많이 알아야 할 수도 있습니다. 그리고 키가 존재하지 않으면 (어떤 형태로 TryGetValue ()를 노출시키는 것이 좋습니다)? 답변과 샘플 코드를 더 완벽하게 만들 수 있습니까?
Peter Mortensen

1

잘 했어, 토마스 ReadOnlyDictionary를 한 단계 더 발전 시켰습니다.

많은 데일의 솔루션처럼, 나는 제거하고 싶어 Add(), Clear(), Remove()인텔리에서 등. 그러나 파생 된 객체가 구현되기를 원했습니다 IDictionary<TKey, TValue>.

또한 다음 코드를 깨고 싶습니다. (다시, Dale의 솔루션 도이 작업을 수행합니다)

ReadOnlyDictionary<int, int> test = new ReadOnlyDictionary<int,int>(new Dictionary<int, int> { { 1, 1} });
test.Add(2, 1);  //CS1061

Add () 줄의 결과는 다음과 같습니다.

error CS1061: 'System.Collections.Generic.ReadOnlyDictionary<int,int>' does not contain a definition for 'Add' and no extension method 'Add' accepting a first argument 

호출자는 여전히을 (를) 전송할 수 IDictionary<TKey, TValue>있지만, NotSupportedException읽기 전용이 아닌 멤버를 사용하려고하면 (Thomas의 솔루션에서) 발생합니다.

어쨌든, 이것을 원했던 사람을위한 나의 해결책은 다음과 같습니다.

namespace System.Collections.Generic
{
    public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
    {
        const string READ_ONLY_ERROR_MESSAGE = "This dictionary is read-only";

        protected IDictionary<TKey, TValue> _Dictionary;

        public ReadOnlyDictionary()
        {
            _Dictionary = new Dictionary<TKey, TValue>();
        }

        public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
        {
            _Dictionary = dictionary;
        }

        public bool ContainsKey(TKey key)
        {
            return _Dictionary.ContainsKey(key);
        }

        public ICollection<TKey> Keys
        {
            get { return _Dictionary.Keys; }
        }

        public bool TryGetValue(TKey key, out TValue value)
        {
            return _Dictionary.TryGetValue(key, out value);
        }

        public ICollection<TValue> Values
        {
            get { return _Dictionary.Values; }
        }

        public TValue this[TKey key]
        {
            get { return _Dictionary[key]; }
            set { throw new NotSupportedException(READ_ONLY_ERROR_MESSAGE); }
        }

        public bool Contains(KeyValuePair<TKey, TValue> item)
        {
            return _Dictionary.Contains(item);
        }

        public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
        {
            _Dictionary.CopyTo(array, arrayIndex);
        }

        public int Count
        {
            get { return _Dictionary.Count; }
        }

        public bool IsReadOnly
        {
            get { return true; }
        }

        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
        {
            return _Dictionary.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return (_Dictionary as IEnumerable).GetEnumerator();
        }

        void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
        {
            throw new NotSupportedException(READ_ONLY_ERROR_MESSAGE);
        }

        bool IDictionary<TKey, TValue>.Remove(TKey key)
        {
            throw new NotSupportedException(READ_ONLY_ERROR_MESSAGE);
        }

        void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
        {
            throw new NotSupportedException(READ_ONLY_ERROR_MESSAGE);
        }

        void ICollection<KeyValuePair<TKey, TValue>>.Clear()
        {
            throw new NotSupportedException(READ_ONLY_ERROR_MESSAGE);
        }

        bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
        {
            throw new NotSupportedException(READ_ONLY_ERROR_MESSAGE);
        }
    }
}


0
public IEnumerable<KeyValuePair<string, string>> MyDictionary()
{
    foreach(KeyValuePair<string, string> item in _mydictionary)
        yield return item;
}

2
또는 다음을 수행 할 수 있습니다.public IEnumerable<KeyValuePair<string, string>> MyDictionary() { return _mydictionary; }
Pat

0

이것은 나쁜 해결책입니다. 하단을 참조하십시오.

여전히 .NET 4.0 또는 이전 버전을 사용하는 사람들에게는 허용되는 답변과 동일한 클래스가 있지만 훨씬 짧습니다. 기존 Dictionary 개체를 확장하여 특정 멤버를 재정의 (실제로 숨겨) 호출하여 예외를 발생시킵니다.

호출자가 내장 사전에있는 추가, 제거 또는 기타 변형 작업을 호출하려고하면 컴파일러에서 오류가 발생합니다. 이 컴파일러 오류를 발생시키기 위해 Obsolete 속성을 사용합니다. 이렇게하면 사전을이 ReadOnlyDictionary로 바꿀 수 있으며 응용 프로그램을 실행하거나 런타임 예외를 기다리지 않고도 문제가있는 위치를 즉시 확인할 수 있습니다.

구경하다:

public class ReadOnlyException : Exception
{
}

public class ReadOnlyDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
    public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
        : base(dictionary) { }

    public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
        : base(dictionary, comparer) { }

    //The following four constructors don't make sense for a read-only dictionary

    [Obsolete("Not Supported for ReadOnlyDictionaries", true)]
    public ReadOnlyDictionary() { throw new ReadOnlyException(); }

    [Obsolete("Not Supported for ReadOnlyDictionaries", true)]
    public ReadOnlyDictionary(IEqualityComparer<TKey> comparer) { throw new ReadOnlyException(); }

    [Obsolete("Not Supported for ReadOnlyDictionaries", true)]
    public ReadOnlyDictionary(int capacity) { throw new ReadOnlyException(); }

    [Obsolete("Not Supported for ReadOnlyDictionaries", true)]
    public ReadOnlyDictionary(int capacity, IEqualityComparer<TKey> comparer) { throw new ReadOnlyException(); }


    //Use hiding to override the behavior of the following four members
    public new TValue this[TKey key]
    {
        get { return base[key]; }
        //The lack of a set accessor hides the Dictionary.this[] setter
    }

    [Obsolete("Not Supported for ReadOnlyDictionaries", true)]
    public new void Add(TKey key, TValue value) { throw new ReadOnlyException(); }

    [Obsolete("Not Supported for ReadOnlyDictionaries", true)]
    public new void Clear() { throw new ReadOnlyException(); }

    [Obsolete("Not Supported for ReadOnlyDictionaries", true)]
    public new bool Remove(TKey key) { throw new ReadOnlyException(); }
}

이 솔루션에는 @supercat이 지적한 문제가 있습니다.

var dict = new Dictionary<int, string>
{
    { 1, "one" },
    { 2, "two" },
    { 3, "three" },
};

var rodict = new ReadOnlyDictionary<int, string>(dict);
var rwdict = rodict as Dictionary<int, string>;
rwdict.Add(4, "four");

foreach (var item in rodict)
{
    Console.WriteLine("{0}, {1}", item.Key, item.Value);
}

예상대로 컴파일 타임 오류를 주거나 런타임 예외를 기대하지 않고이 코드는 오류없이 실행됩니다. 네 개의 숫자를 인쇄합니다. 내 ReadOnlyDictionary를 ReadWriteDictionary로 만듭니다.


이 접근 방식의 문제점은 그러한 객체가 Dictionary<TKey,TValue>컴파일러 불만 이 없을 것으로 예상되는 메소드로 전달 될 수 있으며 일반 사전 유형에 대한 참조를 캐스트 또는 강제 변환하면 보호가 제거된다는 것입니다.
supercat

@ supercat, 쓰레기, 당신 말이 맞아요. 나도 좋은 해결책이 있다고 생각했다.
user2023861

나는의 파생을 기억 Dictionary로모그래퍼 Clone에 체인 것을 방법 MemberwiseClone. 불행하게도, 동안 그것을가 가능해야 효율적으로 복제 사전 후원 저장의 백업 저장소가 있다는 사실 복제에 의한 private것이 아니라 protected방법은 복제 그들에게 파생 클래스 없다 수단을; MemberwiseClone백업 저장소를 복제하지 않고 사용 하면 원본 사전에 대한 후속 수정이 복제본을 손상시키고 복제본에 대한 수정이 원본을 손상시키는 것을 의미합니다.
supercat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.