Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何以一种返回的字典不能更改的方式为字典创建访问器C#/2.0_C#_Generics_Collections_Readonly Collection - Fatal编程技术网

如何以一种返回的字典不能更改的方式为字典创建访问器C#/2.0

如何以一种返回的字典不能更改的方式为字典创建访问器C#/2.0,c#,generics,collections,readonly-collection,C#,Generics,Collections,Readonly Collection,我想到了下面的解决方案,因为集合非常小。但是如果它很大呢 private Dictionary<string, OfTable> _folderData = new Dictionary<string, OfTable>(); public Dictionary<string, OfTable> FolderData { get { return new Dictionary<string,OfTable>(_folderData); }

我想到了下面的解决方案,因为集合非常小。但是如果它很大呢

private Dictionary<string, OfTable> _folderData = new Dictionary<string, OfTable>();

public Dictionary<string, OfTable> FolderData
{
    get { return new Dictionary<string,OfTable>(_folderData); }
}
private Dictionary\u folderData=new Dictionary();
公共字典FolderData
{
获取{返回新字典(_folderData);}
}
通过列表,您可以:

public class MyClass
{
    private List<int> _items = new List<int>();

    public IList<int> Items
    {
        get { return _items.AsReadOnly(); }
    }
}
公共类MyClass
{
私有列表_items=新列表();
公共物品
{
获取{return _items.AsReadOnly();}
}
}
那太好了

提前感谢,干杯&BR-马蒂

现在当我认为集合中的对象在堆中时。所以我的解决方案不会阻止调用者修改它们!!!因为两个字典都包含对同一对象的引用。这是否适用于上面的列表示例

class OfTable
{
    private int _table;
    private List<int> _classes;
    private string _label;

    public OfTable()
    {
        _classes = new List<int>();
    }

    public int Table
    {
        get { return _table; }
        set { _table = value; }
    }

    public List<int> Classes
    {
        get { return _classes; }
        set { _classes = value; }
    }

    public string Label
    {
        get { return _label; }
        set { _label = value; }
    }
}
表类
{
专用int_表;
私人名单(类别);;
私有字符串标签;
公共数据表()
{
_类=新列表();
}
公共整数表
{
获取{return\u table;}
设置{u table=value;}
}
公共列表类
{
获取{return\u classes;}
设置{u classes=value;}
}
公共字符串标签
{
获取{return\u label;}
设置{u label=value;}
}
}
那么如何使这个不可变???

使用类

ReadOnlyCollection泛型类的实例始终为只读。只读集合只是一个带有包装器的集合,该包装器可防止修改集合;因此,如果对基础集合进行了更改,则只读集合将反映这些更改。有关此类的可修改版本,请参见集合

--编辑--

在这里结帐。理查德·卡尔所著。

使用类

ReadOnlyCollection泛型类的实例始终为只读。只读集合只是一个带有包装器的集合,该包装器可防止修改集合;因此,如果对基础集合进行了更改,则只读集合将反映这些更改。有关此类的可修改版本,请参见集合

--编辑--


在这里结帐。Richard Carr所著。

推出自己的
ReadOnlyDictionary
包装类并不困难。大概是这样的:

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

    public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");

        _dictionary = dictionary;
    }

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

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

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

    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]    // Item
    {
        get { return _dictionary[key]; }
    }

    #region IDictionary<TKey, TValue> Explicit Interface Implementation

    void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
    {
        throw new NotSupportedException("Dictionary is read-only.");
    }

    bool IDictionary<TKey, TValue>.Remove(TKey key)
    {
        throw new NotSupportedException("Dictionary is read-only.");
    }

    TValue IDictionary<TKey, TValue>.this[TKey key]    // Item
    {
        get { return _dictionary[key]; }
        set { throw new NotSupportedException("Dictionary is read-only."); }
    }

    #endregion

    #region ICollection<T> Explicit Interface Implementation

    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
    {
        throw new NotSupportedException("Collection is read-only.");
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Clear()
    {
        throw new NotSupportedException("Collection is read-only.");
    }

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

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

    bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
    {
        get { return true; }
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
    {
        throw new NotSupportedException("Collection is read-only.");
    }

    #endregion

    #region IEnumerable Explicit Interface Implementation

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

    #endregion
}
然后从属性返回只读包装:

// in C#2
return new ReadOnlyDictionary<string, OfTable>(_folderData);

// in C#3 or later
return _folderData.AsReadOnly();
//在C#2中
返回新的ReadOnlyDictionary(_folderData);
//在C#3或更高版本中
返回_folderData.AsReadOnly();

推出自己的
ReadOnlyDictionary
包装类并不困难。大概是这样的:

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

    public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");

        _dictionary = dictionary;
    }

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

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

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

    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]    // Item
    {
        get { return _dictionary[key]; }
    }

    #region IDictionary<TKey, TValue> Explicit Interface Implementation

    void IDictionary<TKey, TValue>.Add(TKey key, TValue value)
    {
        throw new NotSupportedException("Dictionary is read-only.");
    }

    bool IDictionary<TKey, TValue>.Remove(TKey key)
    {
        throw new NotSupportedException("Dictionary is read-only.");
    }

    TValue IDictionary<TKey, TValue>.this[TKey key]    // Item
    {
        get { return _dictionary[key]; }
        set { throw new NotSupportedException("Dictionary is read-only."); }
    }

    #endregion

    #region ICollection<T> Explicit Interface Implementation

    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
    {
        throw new NotSupportedException("Collection is read-only.");
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Clear()
    {
        throw new NotSupportedException("Collection is read-only.");
    }

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

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

    bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
    {
        get { return true; }
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
    {
        throw new NotSupportedException("Collection is read-only.");
    }

    #endregion

    #region IEnumerable Explicit Interface Implementation

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

    #endregion
}
然后从属性返回只读包装:

// in C#2
return new ReadOnlyDictionary<string, OfTable>(_folderData);

// in C#3 or later
return _folderData.AsReadOnly();
//在C#2中
返回新的ReadOnlyDictionary(_folderData);
//在C#3或更高版本中
返回_folderData.AsReadOnly();

可能重复的“忽略我的投票”以重复方式关闭。再读一遍,问题就不完全一样了。抱歉。可能重复的“忽略我的投票”以重复结束。再读一遍,问题就不完全一样了。对不起,谢谢!是的,确实如此。很多代码。。。我在StackOverflow中看到了类似的实现。我放弃了你,但做一个包装不是我想要的。对不起,我太挑剔了。如果没有人能用更短的代码给出答案,我会接受。干杯,伙计@matti:是的,有很多代码,但请看其他答案:这在框架中已经为您完成了,即使在底层版本中,这也是完全可重用的代码,因此您只需要编写一次。问题是:包含的对象可以更改。但也许没什么可做的。如果集合和内部对象都是只读的,那就太好了。。。我不是在制作一个代码库,而是一个简单的程序,所以这些都不重要。我只想学习…@matti:没有任何简单的方法可以阻止对字典中存储的对象进行更改(假设它们是引用类型)。如果它们是你自己的自定义对象(例如,<代码>表格>代码>,那么也许你可以考虑使它们不可变。谢谢路加!我为OfTable添加了代码,所以你能告诉我如何使其不可变(这10部分太多了)谢谢!是的,确实如此。很多代码。。。我在StackOverflow中看到了类似的实现。我放弃了你,但做一个包装不是我想要的。对不起,我太挑剔了。如果没有人能用更短的代码给出答案,我会接受。干杯,伙计@matti:是的,有很多代码,但请看其他答案:这在框架中已经为您完成了,即使在底层版本中,这也是完全可重用的代码,因此您只需要编写一次。问题是:包含的对象可以更改。但也许没什么可做的。如果集合和内部对象都是只读的,那就太好了。。。我不是在制作一个代码库,而是一个简单的程序,所以这些都不重要。我只想学习…@matti:没有任何简单的方法可以阻止对字典中存储的对象进行更改(假设它们是引用类型)。如果它们是你自己的自定义对象(例如,<代码>表格>代码>,那么也许你可以考虑使它们不可变。谢谢路加!我为OfTable添加了代码,所以你能告诉我如何使其不可变(这其中的10部分太多了)@Matti:为了让它有帮助,请查看我的编辑以回应你的评论。@Matti:为了让它有帮助,请查看我的编辑以回应你的评论。