c# - 如何让 KeyedCollection 成为只读的?

标签 c# .net collections keyedcollection

首先让我解释一下为什么我要使用 KeyedCollection。我正在构建一个 DLL,我有一个项目列表,我需要将它们添加到一个集合中,并让它们保持我放置它们的顺序,但我还需要通过它们的索引和键来访问它们(键是我已经定义的对象的属性)。如果有任何其他更简单的集合可以执行此操作,请告诉我。

现在,我需要能够在 DLL 内部向这个集合添加项目,但我需要它以只读方式对 DLL 的最终用户公开可用,因为我不希望他们删除/更改我添加的项目。

我搜索了整个网站、其他网站、一般的谷歌,但我一直无法找到获取某种只读 KeyedCollection 的方法。我最接近的是这个页面 ( http://www.koders.com/csharp/fid27249B31BFB645825BD9E0AFEA6A2CCDDAF5A382.aspx?s=keyedcollection#L28 ),但我无法让它正常工作。

更新:

我看了一下那些 C5 类。那连同您的其他评论,帮助我更好地理解了如何创建自己的只读类并且它似乎有效。但是,当我尝试将常规的转换为只读的时,我遇到了问题。我收到编译时无法转换错误。这是我创建的代码(第一个小类是我最初拥有的):

public class FieldCollection : KeyedCollection<string, Field>
{
    protected override string GetKeyForItem(Field field)
    {
        return field.Name;
    }
}

public class ReadOnlyFieldCollection : KeyedCollection<string, Field>
{
    protected override string GetKeyForItem(Field field)
    { return field.Name; }

    new public void Add(Field field)
    { throw new ReadOnlyCollectionException("This collection is read-only."); }

    new public void Clear()
    { throw new ReadOnlyCollectionException("This collection is read-only."); }

    new public void Insert(int index, Field field)
    { throw new ReadOnlyCollectionException("This collection is read-only."); }

    new public bool Remove(string key)
    { throw new ReadOnlyCollectionException("This collection is read-only."); }

    new public bool Remove(Field field)
    { throw new ReadOnlyCollectionException("This collection is read-only."); }

    new public bool RemoveAt(int index)
    { throw new ReadOnlyCollectionException("This collection is read-only."); }
}

如果我定义了这个变量:

private FieldCollection _fields;

然后这样做:

public ReadOnlyFieldCollection Fields;
Fields = (ReadOnlyFieldCollection)_fields;

编译失败。他们都继承自同一个类,我认为他们会“兼容”。如何将集合转换(或公开)为我刚刚创建的只读类型?

最佳答案

我也不知道有任何内置解决方案。这是我在评论中给出的建议示例:

    public class LockedDictionary : Dictionary<string, string>
    {
        public override void Add(string key, string value)
        {
            //do nothing or log it somewhere
            //or simply change it to private
        }

        //and so on to Add* and Remove*

        public override string this[string i]
        {
            get
            {
                return base[i];
            }
            private set
            {
                //...
            }
        }
    }

您将能够遍历 KeyValuePair 列表和其他所有内容,但它不可用于写入操作。 请确保根据您的需要键入它。


编辑 为了有一个排序列表,我们可以将基类从 Dictionary<T,T> 更改为到 Hashtable .

看起来像这样:

    public class LockedKeyCollection : System.Collections.Hashtable
    {
        public override void Add(object key, object value)
        {
            //do nothing or throw exception?
        }

        //and so on to Add* and Remove*

        public override object this[object i]
        {
            get
            {
                return base[i];
            }
            set
            {
                //do nothing or throw exception?
            }
        }
    }

用法:

        LockedKeyCollection aLockedList = new LockedKeyCollection();

        foreach (System.Collections.DictionaryEntry entry in aLockedList)
        {
            //entry.Key
            //entry.Value
        }

不幸的是,我们无法更改方法的访问修饰符,但我们可以重写它们什么也不做。

关于c# - 如何让 KeyedCollection 成为只读的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11908527/

相关文章:

.net - ORA-01425 : escape character must be character string of length 1

c# - Web 应用程序中基于文化的 ToString() 方法

java - 映射中值的所有直接和间接键

collections - 为什么 HashSet<T> 不实现 IReadOnlyCollection<T>?

c# - 滚动到列表框 wp7 的底部

c# - Microsoft.WindowsAzure.Storage.dll 中发生了类型 'Microsoft.WindowsAzure.Storage.StorageException' 的第一次机会异常

c# - 如何使用 SharpDX 绘制透明表面?

c# - 使用组合框作为搜索条件

c# - 如何以编程方式调用 Windows 权限对话框?

Java 集合 : IF the key of Hashmap is Immutable Object then do we need to override hashcode and equals?