链接列表的只读包装器。如何?

时间:2009-11-19 11:22:24

标签: .net list .net-2.0 readonly

.NET v2

当List有一个非常有用的(4 me)方法时AsReadOnly() LinkedList没有这样的方法。

有没有办法“快速”将内部 LinkedList 连接到只读外部代码?

4 个答案:

答案 0 :(得分:9)

为什么不返回IEnumerable<T>?如果你只是想让用户枚举列表而不修改它*,IEnumerable是显而易见的选择。

如果您想拥有LinkedList接口的只读接口,可以将LinkedList,转发只读方法包装到包装列表中并拒绝任何更改。

*)请记住,ReadOnlyCollection和IEnumerable都不会阻止调用者在引用类型集合的情况下更改对象的状态。如果对象也应该只读,则需要将其作为其类型的一部分来实现。

答案 1 :(得分:4)

ReadOnlyCollection<T>IList<T>作为构造函数的参数。 LinkedList<T>未实现此接口。 List<T>有一个构造函数重载,它以IEnumerable<T>为参数,LinkedList<T>实现了这个接口。所以以下内容应该有效:

LinkedList<int> linked = new LinkedList<int>();
// populate the list

ReadOnlyCollection<int> readOnly = new ReadOnlyCollection<int>(
    new List<int>(linked));

它使用List<T>的实例将项目带入ReadOnlyCollection<T>构造函数。

答案 2 :(得分:0)

LinkedList<T>没有实现IList所以简而言之,没有办法快速做到这一点。如果将LinkedList转换为List,则可能会丢失所需的功能。

LinkedList<T>没有为子类化提供任何内容,因此您需要编写自己的子类。我想下一个请求是“你能告诉我该怎么做”

答案 3 :(得分:0)

#1修复链接列表

class FixedLinkedList<T> : LinkedList<T>, IList<T>
{
    public T this[int index]
    {
        get
        {
            return GetAt(index).Value;
        }
        set
        {
            GetAt(index).Value = value;
        }
    }

    public int IndexOf(T item)
    {
        int i = 0;
        var node = First;
        while (node!= null && !node.Value.Equals(item))
        {
            i++;
            node = node.Next;
        }

        if (node == null)
        {
            return -1;
        }

        return i;
    }

    public void Insert(int index, T item)
    {
        AddBefore(GetAt(index), new LinkedListNode<T>(item));
    }


    public void RemoveAt(int index)
    {
        Remove(GetAt(index));
    }

    private LinkedListNode<T> GetAt(int index)
    {
        CheckIndex(index);
        int i = 0;
        var node = First;
        while (i < index)
        {
            i++;
            node = node.Next;
        }

        return node;
    }

    private void CheckIndex(int index)
    {
        if (index < 0)
        {
            throw new ArgumentOutOfRangeException(
                nameof(index),
                "Parameter must be greater or equal to 0.");
        }

        if (index >= Count)
        {
            throw new ArgumentOutOfRangeException(
                nameof(index),
                "Parameter must be lower than the list item Count.");
        }
    }
}

#2将其实例包装在ReadOnlyCollection中