【问题标题】:Read-Only List in C#C#中的只读列表
【发布时间】:2011-01-13 12:31:47
【问题描述】:

我有 List-property 的课程:

class Foo {
  private List<int> myList;
}

我只想提供对该字段的访问权限以供阅读。

即我想要可以访问 Enumerable、Count 等但无法访问 Clear、Add、Remove 等的属性。我该怎么做?

【问题讨论】:

标签: c# .net list


【解决方案1】:

您可以使用AsReadOnly() 方法将List&lt;T&gt; 公开为ReadOnlyCollection&lt;T&gt;

C# 6.0 及更高版本(使用Expression Bodied Properties

class Foo { 

  private List<int> myList;

  public ReadOnlyCollection<int> ReadOnlyList => myList.AsReadOnly();

}

C# 5.0 及更早版本

class Foo {

  private List<int> myList;

  public ReadOnlyCollection<int> ReadOnlyList {
     get {
         return myList.AsReadOnly();
     }
  }
}

【讨论】:

  • 漂亮干净,正是我想要的。
  • 我觉得myList之前应该有一个return
【解决方案2】:

如果您想要一个列表的只读视图,您可以使用ReadOnlyCollection&lt;T&gt;

class Foo {
    private ReadOnlyCollection<int> myList;
}

【讨论】:

  • 或者,更准确地说,是一个私有的List&lt;int&gt; 变量和一个公共的ReadOnlyCollection&lt;int&gt; 属性以及一个返回该变量的get {}
  • @Victor:这将使调用代码通过简单的强制转换访问可变列表。可能不是OP想要的。 readonly 属性可以return new ReadOnlyCollection&lt;int&gt;(myList);
  • ReadOnlyCollection 并不是真正不可变的,因为它包含指向原始列表的指针 - 如果您向列表中添加某些内容,readOnly-instance 也可以访问这个新项目......但是,你是对的,当涉及到修改方法时 - 这些都不见了!
  • @Andreas:OP并未声明列表内容不得更改;唯一的要求是调用代码不能改变它。
  • @FredrikMörk:因为标题说“不可变”。或许应该改为“只读”。
【解决方案3】:

我会去

public sealed class Foo
{
    private readonly List<object> _items = new List<object>();

    public IEnumerable<object> Items
    {
        get
        {
            foreach (var item in this._items)
            {
                yield return item;
            }
        }
    }
}

【讨论】:

  • 为什么要在最后打扰产量中断?
  • Foo 也可以实现 IEnumerable
  • @Jon Skeet:只是复制过去...起初我有一个// TODO,但用 foreach 代替了它...感谢您的提示!
  • @Turek:jep,确实......但如未说明,我没有考虑到这一点 - 也许 OP 需要更多属性(列表)
【解决方案4】:

现在有一个不可变集合库可以做到这一点。您可以通过 nuget 安装。

从 .NET 开始支持不可变集合类 框架 4.5。

https://msdn.microsoft.com/en-us/library/dn385366%28v=vs.110%29.aspx

System.Collections.Immutable 命名空间提供通用的不可变 可用于这些场景的集合类型,包括: 不可变数组, 不可变字典, ImmutableSortedDictionary,ImmutableHashSet, ImmutableList、ImmutableQueue、ImmutableSortedSet、 不可变堆栈

使用示例:

class Foo
{
    public ImmutableList<int> myList { get; private set; }

    public Foo(IEnumerable<int> list)
    {
        myList = list.ToImmutableList();
    }
}

【讨论】:

  • ImmutableList 确实允许您添加新元素,它只是为此创建另一个列表对象。 Note that these methods return a new object. When you add or remove items from an immutable list, a copy of the original list is made with the items added or removed, and the original list is unchanged. 这个答案不应该被赞成。
【解决方案5】:

如果您在班级中声明只读列表,您仍然可以向其中添加项目。

如果您不想添加或更改任何内容,您应该按照 Darin 的建议使用 ReadOnlyCollection&lt;T&gt;

如果您想从列表中添加、删除项目但不想更改内容,您可以使用readonly List&lt;T&gt;

【讨论】:

    猜你喜欢
    • 2016-06-14
    • 1970-01-01
    • 2015-05-21
    • 2013-07-02
    • 2011-06-12
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多