代码之家  ›  专栏  ›  技术社区  ›  Konrad

ICollection属性和封装

  •  0
  • Konrad  · 技术社区  · 6 年前

    考虑到我想封装我的属性,使用接口是不是不好?

    public class Order
    {
        private readonly ICollection<OrderItem> _orderItems;
        public IReadOnlyCollection OrderItems => _orderItems; // not possible without ToList
    }
    

    因为没有办法转换成 IReadOnlyCollection IEnumerable ICollection 不使用 ToList 首先是复制整个集合。

    我应该把它定义为:

    private readonly Collection<OrderItem> _orderItems;
    

    private readonly HashSet<OrderItem> _orderItems;
    

    private readonly List<OrderItem> _orderItems;
    

    相反?

    2 回复  |  直到 6 年前
        1
  •  1
  •   CodeNotFound dotnetstep    6 年前

    您应该遵循的规则是,私有成员只对定义它们的类可见,因此您可以将类型定义为 List<T> Hashset<T> Collection<T> ,如果以后修改类型,则使用类程序集的其他开发人员将不会受到中断更改的影响。

    你可以从你提出的三个问题中选择一个,只要你知道 Hasset<T> vs List<T> List<T> vs Collection<T> .

    所以移除接口 ICollection<OrderItem> 作为你的一种类型 私有的 如果您不想调用 ToList() 在里面 OrderItems 实施。

        2
  •  0
  •   Bagdan Gilevich    6 年前

    您可以编写自己的扩展来将icollection转换为ireadonlycollection

    public static class CollectionExtensions
    {
        public static IReadOnlyCollection<T> AsReadOnly<T>(this ICollection<T> source)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            return source as IReadOnlyCollection<T> ?? new ReadOnlyCollectionAdapter<T>(source);
        }
        sealed class ReadOnlyCollectionAdapter<T> : IReadOnlyCollection<T>
        {
            ICollection<T> source;
            public ReadOnlyCollectionAdapter(ICollection<T> source) { this.source = source; }
            public int Count { get { return source.Count; } }
            public IEnumerator<T> GetEnumerator() { return source.GetEnumerator(); }
            IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
        }
    }