使列表项只读

3

可能是重复问题:
如何在私有属性中使用只读List<T>

我有一个类:

public SomeClass{

        public List<Status> log { get; private set; }

        public enum Status
        {
            waitingForConnection,
            connected,
            receivingFile,
            doneReceivingFile
        }

        // later I initialize log and populate it...
       ///

}

目前很容易看出我只能在类内部设置新的日志列表。如何防止用户编辑列表中的项目。换句话说,我不希望用户能够执行以下操作:

SomeClass someClass = new SomeClass();
//....
someClass.log[3] = \\different value

如果我将列表日志设为私有,那么我就能实现这个功能,但是我想让用户能够查看日志列表的内容,但不能编辑其中的项目。
另外,我也不想将公共枚举状态(Status)设为私有,以便用户能够查看状态...
那么我该如何限制用户编辑列表中的项目呢?

1
请查看此线程中的答案:https://dev59.com/lW445IYBdhLWcg3wq8FY - Greg Andora
5个回答

4
使用 ReadOnlyCollection 来实现。另外需要注意的是,readonly 关键字并不能真正使集合变为只读。
private List<Status> m_Log = new List<Status>();

public ReadOnlyCollection<Status> Log {
    get {
        return m_Log.AsReadOnly();
    }
}

我很喜欢这个,但它需要NET4.5或更高版本。 - Zéiksz
ReadOnlyCollection<T> 从2.0版本就存在了。 - David Anderson

4

3
不要将您的属性定义为 List<Status>。请实现一个只读索引器属性。
class Log {
  private readonly List<Status> statuses;
  public Log(List<Status> items)
  {
     statuses = items;
  }
  public Status this[int i]
  {
      get { return statuses[i]; }
  }
}

public SomeClass
{
   public Log log { get; private set; }
}

这并不会阻止消费者执行类似 instance.Log[0].SomeProperty = 10 这样的操作,对吗? - nphx

1
如何将日志列表设为私有,并拥有一个公共的 get() 属性呢?

0

你可以选择让SomeClass继承IEnumerable<T>接口。

这将使你履行合同并实现GetEnumerator方法。只需返回列表的枚举器即可。现在可以将其用作只读IEnumerable集合。

编辑
我再次查看了一下,意识到你只需要添加一个属性getter:

IEnumerable<Status> StatusList
{
    foreach (Status item in log)
    {
        yield return item;
    }
}

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