重构指南,net还宝贵相逢那样意想不到的景况

重构指南,net还宝贵相逢那样意想不到的景况

图片 1

C#中之所以有集聚那些东东,是因为数组的尺寸是定位的,而实在供给是,不明确今后那几个“数组”的个数,故现身集结那一个概念,因为集合的容积会随成分的加码曾倍数增进。C#中有2类常用集合:ArrayList,泛型版本是List<T>(雷同数组集结)和Hashtable,泛型版本是Dictionary<K,V>(键值对聚集),未来评论下ArrayList集合

包裹正是将相关的格局照旧性质抽象成为二个指标。

那是Prism中蒙受的难点,然则放在日常景色下,也很奇异诶。图中的c明明不是null,可是调用Remove方法却报错:该区域不分包内定的视图。那就类似理解一个群集中有三个因素,调用Remove方法,却告知会集中绝非成分……

刚才说群集的体积会随成分的充实曾倍数增加,请看代码:

包裹的意义:

  1. 对外掩瞒个中得以完毕,接口不改变,内部贯彻自由修正。
  2. 只回去要求的数据和办法。
  3. 提供生龙活虎种方式防止数据被更改。
  4. 越来越好的代码复用。

当三个类的性质类型为汇集,也许措施重临类型为汇集时,假若相符以下原则,我们就足以思考将聚合进行包装:

  1. 再次回到的数量仅用于显示
  2. 当集合的Add,Remove方法包涵别的专门的工作逻辑

向类的调用者隐敝类中的完整集合犹如下多少个低价:

  1. 管教再次回到的集聚数据不会被退换。
  2. 在Add, Remove方法中能够加上验证,日志或别的职业逻辑。

代码示例:

using System.Collections.Generic;

namespace LosTechies.DaysOfRefactoring.EncapsulateCollection.Before
{
    public class Order
    {
        private List<OrderLine> _orderLines;
        private double _orderTotal;

        public IList<OrderLine> OrderLines
        {
            get { return _orderLines; }
        }

        public void AddOrderLine(OrderLine orderLine)
        {
            _orderTotal += orderLine.Total;
            _orderLines.Add(orderLine);
        }

        public void RemoveOrderLine(OrderLine orderLine)
        {
            orderLine = _orderLines.Find(o => o == orderLine);

            if (orderLine == null)
                return;

            _orderTotal -= orderLine.Total;
            _orderLines.Remove(orderLine);
        }
    }

    public class OrderLine
    {
        public double Total { get; private set; }
    }
} 

 

上面的代码在Add或许Remove
orderLine时存在工作逻辑,要是调用时一直改过OrderLines的成分,就能够发出bug,所以须要重构如下:

 

using System.Collections.Generic;

namespace LosTechies.DaysOfRefactoring.EncapsulateCollection.After
{
    public class Order
    {
        private List<OrderLine> _orderLines;
        private double _orderTotal;

//方法一:返回IEnumerable类型
        public IEnumerable<OrderLine> OrderLines
        {
            get { return _orderLines.Skip(0); }
        }

//方法二:返回只读类型
         public ReadOnlyCollection<OrderLine> OrderLines
        {
            get { return _orderLines.AsReadOnly(); }
        }
        public void AddOrderLine(OrderLine orderLine)
        {
            _orderTotal += orderLine.Total;
            _orderLines.Add(orderLine);
        }

        public void RemoveOrderLine(OrderLine orderLine)
        {
            orderLine = _orderLines.Find(o => o == orderLine);

            if (orderLine == null)
                return;

            _orderTotal -= orderLine.Total;
            _orderLines.Remove(orderLine);
        }
    }

    public class OrderLine
    {
        public double Total { get; private set; }
    }
}

 

注意:虽然向来回到IEnumerable,那样只好遍历收取它的值,可是还是能够由此转移为List后操作集结中的元素,所以大家利用_orderLines.Skip(0State of Qatar迭代回到,那样就能够挡住调用者转变为list。

1             ArrayList aList = new ArrayList();
2             aList.Add(9);
3             aList.Add(new Person() { ID = 1, Name = "yzk", Age = 18 });
4             aList.Add("80");
5             aList.AddRange(new int[] { 4, 5, 6, 7, 8 });
6             aList.AddRange(new string[] { "张三", "李四", "王五" });
7             Console.WriteLine("容量:" + aList.Capacity);
8             Console.WriteLine("含元素个数:" + aList.Count);
9             Console.ReadKey();

运作结果如下:

图片 2

需求静心的是,集结中的Add方法只可以增添多少个成分,哪怕里面是数组也只以为是二个因素,而AddRange则以为增添“一些”成分,里面每一种成分都以聚众中的单个成分。

当体量为8,成分<=8时不抓好,>8后,增添至16.

调用ArrayList的Remove(State of Qatar和RemoveAt(卡塔尔(قطر‎,能够去除集结中的元素。

 1 ArrayList aList = new ArrayList();
 2             aList.Add(9);
 3             aList.Add(new Person() { ID = 1, Name = "yzk", Age = 18 });
 4             aList.Add("80");
 5             aList.AddRange(new int[] { 4, 5, 6, 7, 8 });
 6             aList.AddRange(new string[] { "张三", "李四", "王五" });
 7             aList.Add(new string(new char[]{'a','b','c'}));
 8             aList.Remove("80");
 9             aList.Remove("abc");
10             Console.WriteLine("容量:" + aList.Capacity);
11             Console.WriteLine("含元素个数:" + aList.Count);

运行结果如下:

图片 3

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图