문제

거기에 아무것도 내장되어 핵심 C#라이브러리를 줄 수 있는 나에게 변경할 수 없는 사전?

의 라인을 따라 뭔가 Java:

Collections.unmodifiableMap(myMap);

그냥을 명확히 하기 위해,나를 찾지 키/값을 스스로의 변경,단체의 구조는 사전.내가 원하는 무언가 실패하는 빠르고 큰 소리로 어떤 경우의 IDictionary 의 방법을 변경자는 불(Add, Remove, Clear).

도움이 되었습니까?

해결책

지 않지만,래퍼가 오히려 사소한:

public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    IDictionary<TKey, TValue> _dict;

    public ReadOnlyDictionary(IDictionary<TKey, TValue> backingDict)
    {
        _dict = backingDict;
    }

    public void Add(TKey key, TValue value)
    {
        throw new InvalidOperationException();
    }

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

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

    public bool Remove(TKey key)
    {
        throw new InvalidOperationException();
    }

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

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

    public TValue this[TKey key]
    {
        get { return _dict[key]; }
        set { throw new InvalidOperationException(); }
    }

    public void Add(KeyValuePair<TKey, TValue> item)
    {
        throw new InvalidOperationException();
    }

    public void Clear()
    {
        throw new InvalidOperationException();
    }

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

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

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

    public bool IsReadOnly
    {
        get { return true; }
    }

    public bool Remove(KeyValuePair<TKey, TValue> item)
    {
        throw new InvalidOperationException();
    }

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

    System.Collections.IEnumerator 
           System.Collections.IEnumerable.GetEnumerator()
    {
        return ((System.Collections.IEnumerable)_dict).GetEnumerator();
    }
}

분명을 변경할 수 있습니다 이것[]setter 위도록 허용하려는 경우 수정하는 값입니다.

다른 팁

의 출시와 함께.NET4.5,새로운 ReadOnlyDictionary 클래스입니다.당신은 단순히 전달 IDictionary 을 생성자를 만들은 변경할 수 없는 사전.

은 도움이 확장하는 방법을 간소화하는 데 사용할 수 있을 만드는 읽기 전용어 사전입니다.

나는 그렇게 생각하지 않습니다.가 있을 만들 수 있는 방법을 읽기만 나열하고 읽기만 컬렉션,하지만 나는 생각하지 않재되어 있어서 읽기 전용어 사전입니다.시스템입니다.논는 ReadOnlyDictinoary 구현하지만,그 내부에 있습니다.아마 없을 것이 너무 힘을 복사하지만 그것을 사용하여,반사체,또는 단순히 처음부터 자신을 만들.그것은 기본적으로 감싸는 사전에 던졌을 때 변경자가 호출됩니다.

에 추가 dbkk 의 응답, 고 싶었어를 사용할 수 있는 객체에 이니셜라이저 때 처음으로 만들어 내 ReadOnlyDictionary.나는 다음과 같이 수정:

private readonly int _finalCount;

/// <summary>
/// Takes a count of how many key-value pairs should be allowed.
/// Dictionary can be modified to add up to that many pairs, but no
/// pair can be modified or removed after it is added.  Intended to be
/// used with an object initializer.
/// </summary>
/// <param name="count"></param>
public ReadOnlyDictionary(int count)
{
    _dict = new SortedDictionary<TKey, TValue>();
    _finalCount = count;
}

/// <summary>
/// To allow object initializers, this will allow the dictionary to be
/// added onto up to a certain number, specifically the count set in
/// one of the constructors.
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
public void Add(TKey key, TValue value)
{
    if (_dict.Keys.Count < _finalCount)
    {
        _dict.Add(key, value);
    }
    else
    {
        throw new InvalidOperationException(
            "Cannot add pair <" + key + ", " + value + "> because " +
            "maximum final count " + _finalCount + " has been reached"
        );
    }
}

지금 사용할 수 있습니다 클래스는 다음과 같이

ReadOnlyDictionary<string, string> Fields =
    new ReadOnlyDictionary<string, string>(2)
        {
            {"hey", "now"},
            {"you", "there"}
        };

오픈 소스 PowerCollections 라이브러리에는 읽기 전용어 사전 래퍼(뿐만 아니라 읽기 전용으로 포장지에 대한 거의 모든 다른 사람),를 통해 액세스할 수 있는 정적 ReadOnly() 메서드 Algorithms 클래스입니다.

중 하나는 해결 방법이 될 수 있을 던져 새로운 목록의 온라인 설문 조에서 사전 유지하는 원래의 수정되지 않습니다.

var dict = new Dictionary<string, string>();

dict.Add("Hello", "World");
dict.Add("The", "Quick");
dict.Add("Brown", "Fox");

var dictCopy = dict.Select(
    item => new KeyValuePair<string, string>(item.Key, item.Value));

// returns dictCopy;

이 방법으로 원래는 사전지 않을 것을 얻을 수정합니다.

"상자에서"이 없이 작업을 수행하는 방법입니다.을 만들 수 있습 중 하나에 의해 파생된 자신의 사전 클래스를 구현하는 대한 제한할 필요합니다.

내가 찾는의 구현 Inmutable(지 READONLY)의 구현 AVLTree C#여기에.

AVL 나무는 대수(일정하지 않)비용에서 각 작업이지만 빠르다.

http://csharpfeeds.com/post/7512/Immutability_in_Csharp_Part_Nine_Academic_Plus_my_AVL_tree_implementation.aspx

이 Linq 에 있는 일반 인터페이스 ILookup.더 읽기 MSDN.

따라서,단순히 얻기 위해 변경할 수 없는 사전에 당신을 호출 수 있습니다:

using System.Linq;
// (...)
var dictionary = new Dictionary<string, object>();
// (...)
var read_only = dictionary.ToLookup(kv => kv.Key, kv => kv.Value);

당신이 시도할 수 있습 무언가 이것을 좋아한다:

private readonly Dictionary<string, string> _someDictionary;

public IEnumerable<KeyValuePair<string, string>> SomeDictionary
{
    get { return _someDictionary; }
}

이를 제거하는 것은 가변성 문제에의 호의는 발신자가 하나로 변환하여 그것을 자신의 사:

foo.SomeDictionary.ToDictionary(kvp => kvp.Key);

...를 사용하거나 비교 작업에 열쇠가 아닌 인덱스 조회,예를 들어:

foo.SomeDictionary.First(kvp => kvp.Key == "SomeKey");

일반적으로 그것은 훨씬 더 좋은 생각을 전달하지 않는 어떤 사전에서 첫 번째 장소(지 않는 경우가 있습니다).

대신 도메인을 만들-체와 함께하는 인터페이스를 제공하지 않는 어떤 방법 수정하기 사전(는 랩).대신에 제공하는 데 필요한 조회 방법을 검색하는 요소에서 사전에 키(보너스입니다 그것은 쉽게 사용하기보다는 사전뿐만 아니라).

public interface IMyDomainObjectDictionary 
{
    IMyDomainObject GetMyDomainObject(string key);
}

internal class MyDomainObjectDictionary : IMyDomainObjectDictionary 
{
    public IDictionary<string, IMyDomainObject> _myDictionary { get; set; }
    public IMyDomainObject GetMyDomainObject(string key)         {.._myDictionary .TryGetValue..etc...};
}

또 다른 대안으로 나가에서 설명:

http://www.softwarerockstar.com/2010/10/readonlydictionary-tkey-tvalue/

기본적으로 그것의 하위 readonlycollection 를>을 얻을 수있는,작업에서 수행하는 더 우아하는 방식이다.우아한다는 의미에서 그것은 컴파일시 지원을 만들기 위한 사전 읽기 전용 던지는 것이 아니라 예외에서 방법을 수정하는 항목입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top