readonly关键字是否能使List<>只读?

33

我有以下代码在一个公共静态类中:

public static class MyList
{
    public static readonly SortedList<int, List<myObj>> CharList;
    // ...etc.
}

..但即使使用 readonly,我仍然可以从另一个类向列表中添加项目:

MyList.CharList[100] = new List<myObj>() { new myObj(30, 30) };

或者

MyList.CharList.Add(new List<myObj>() { new myObj(30, 30) });

有没有一种方法可以使这件事只读,而不改变CharList的实现(这会破坏一些东西)? 如果我必须改变实现(使它不可更改),哪种方式最好? 我需要它成为List<T, T>,因此ReadOnlyCollection行不通。


注:ReadOnlyCollection是只读集合类,但不支持泛型参数为两个类型的情况。

返回一个 List(Of T).AsReadOnly - Tim Schmelter
3个回答

62

修饰符readonly表示该值除了在声明或构造函数中赋值外,不能再被赋值。它并不意味着所赋的对象变成不可变。

如果您希望对象是不可变的,您必须使用一个不可变的类型。您提到的ReadOnlyCollection<T>类型是不可变集合的一个例子。请参见此相关问题以了解如何为字典实现相同的效果:


问题提到:“我需要它是List<T, T>,所以ReadOnlyCollection行不通”,而据我所知没有ReadOnlyDictionary - user743382
请看我添加的链接:“.NET中是否有可用的只读通用字典?” - Mark Byers
3
哦。正如那个问题中的一个答案所暗示的那样,事实证明,.NET 4.5 已经有了一个 ReadOnlyDictionary 。很酷。 - user743382
@hvd:发现得不错,我没注意到。你给它投了赞成票吗?它获得的赞成票越多,越有可能被更多人看到。 - Mark Byers

3

readonly修饰符只是保证了变量'CharList'不能从类构造函数之外的地方被重新赋值。你需要创建自己的字典结构,不要有公共的Add()方法。

class ImmutableSortedList<T, T1> 
{
    SortedList<T, T1> mSortedList;

    public ImmutableSortedList(SortedList<T, T1> sortedList) // can only add here (immutable)
    {
        this.mSortedList = sortedList; 
    }

    public implicit operator ImmutableSortedList<T, T1>(SortedList<T, T1> sortedList)
    {
        return new ImmutableSortedList<T, T1>(sortedList); 
    }
}

或者,如果你真的无法更改实现方式,则将SortedList设置为私有,并添加自己的方法来控制访问:

class MyList
{
    // private now
    readonly SortedList<int, List<myObj>> CharList;

    // public indexer
    public List<myObj> this[int index]
    {
        get { return this.CharList[index]; }
    }
}

1

列表有一个AsReadOnly方法,它返回一个只读列表,这可能是你想要的。


2
但是 SortedList<TKey, TValue> 不行。 - user743382
它返回一个 ReadOnlyCollection<T>。 - Rick the Scapegoat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接