【问题标题】:Clear property-(public) List without clearing the private List清除属性-(公共)列表而不清除私有列表
【发布时间】:2017-05-16 17:37:10
【问题描述】:

我是 C# 新手(第一篇文章),目前正在解决有关“封装”的问题。 基本上我有两个这样的类(简化):

class Myclass
    {

        private List<X> _list;
        public List<X> list
        {
            get
            {
                return _list;
            }
        }
        ...
        public Myclass (List<X> input)
        {
          _list = new List <X>(input);
        }
        ...
     }

class Testclass
    {
      List<X> inputList = new List<X>() {"bla", "bla"};
      Myclass myclass = new Myclass(inputlist);

      myclass.list.Clear();
      List<X> newL = myclass.list;
    }

我不应该对第二类“Testclass”进行任何更改。

这是我的问题: myclass.list.Clear() 清除公共列表和私有列表。但我只希望它清除公共列表或什么都不做,因为最后我需要列表 newL 填充私人列表中的项目(通过 get-accessor 的公共列表)。

因为我应该在不接触第二节课的情况下解决问题,所以我不知道该怎么办。 有人告诉我,公共列表称为属性,对吗?如果有,公开名单叫什么?

就像我说的,我在一般编程方面相当糟糕/新手(19 岁),所以非常感谢初学者友好的答案!

【问题讨论】:

    标签: c# list private encapsulation


    【解决方案1】:
    public List<X> list
    {
        get
        {
            return new List<X>(_list);
        }
    }
    

    这将每次返回列表的副本。因此,从外部来看,调用者永远无法访问内部的 real 列表。他可以随心所欲地处理副本,清除、添加、删除。它不会改变私人名单。

    请注意,在实际生产代码中,您将改为更改属性以不返回列表,但某些内容根本没有 更改它的选项(如IEnumerable&lt;T&gt;)。给某人一个 List 然后忽略他对它所做的任何事情对于调用者来说是非常不直观的,也不是很好的编程。

    【讨论】:

    • 据我了解的完美答案。完全有道理。非常感谢,我会在一秒钟内测试它:)
    • 你也可以用return _list.ToList()代替新的构造函数(不知道哪个效率最高)
    • @fharreau 正如.ToList()exactly the same 作为我的代码行,使用列表构造函数可以被视为稍微更有效(节省空检查)。由于这不是人们应该关心的效率水平,所以使用最能提高可读性的任何东西。
    • 测试了它,它的工作原理!感谢您的帮助:) 现在快乐!
    • 这个答案是正确的,但是克隆(或复制)列表的成本很高,尤其是在每次访问属性时都这样做。如果属性被更频繁地访问,那么字段的值会发生变化,使用ReadOnlyCollection 会更好吗?
    【解决方案2】:

    当通过您的属性访问列表时,它是列表的实例,存储在您的 (backing-) 字段中,因此两个列表是同一个对象。这就是为什么在现场调用您的Clear 的原因。要以只读方式传递列表,您有两种可能性:

    • 您可以克隆列表:这样,返回的列表不是同一个对象,而是与原始列表具有相同的元素。示例:return _list.ToList();return new List(_list);

    • 您可以使用ReadOnlyCollection&lt;T&gt;。顾名思义,这是只读的,因此没有人可以添加或删除项目。

    【讨论】:

    • 感谢您的回答!有用!
    猜你喜欢
    • 1970-01-01
    • 2015-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 1970-01-01
    • 2018-11-03
    • 2015-08-10
    相关资源
    最近更新 更多