• WPF依赖属性(续)(1)


          
             之前有写过几篇文章,详细地介绍了依赖属性的基本使用方法,如果你不想了解其内部实现机制的话,那么通过那两篇文章的介绍,足以应付平时的应用了.关于其内部实现,博客园的周永恒也有人详细介绍过,还原了依赖属性的实现.通过阅读后和阅读源代码并为了加深理解,下面则继续依赖属性的探讨.

    属性内存问题

    如下代码,Name有一个默认的空字符串,Test1方法添加了10000个对象,那么在没有改变People 的Name属性情况下,同时也创建了10000个空字符串

    public class People
    {
        private string _name="";
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
    }
    
    public class EntityTest
    {
        public void Test1()
        {
            List<People> list=new List<People>();
            for (int i = 0; i < 10000; i++)
            {
                list.Add(new People());
            }
        }
    }

    问题
    :本一个默认值可以解决的问题,却用了10000个对象去解决,浪费了内存.
    思路:为属性创建一个默认值

    创建属性默认值

    将_name字段改为静态
    private static string _name="";
    问题:虽然引用同一个内存,但当任意修改一个对象的Name属性时,则全部发生了变更.
    思路:提供默认值,如属性值发生变更,则使用修改的值,但不影响其他对象
    代码改进如下
    public class People
    {
        private static string _name="";
    
        private static Dictionary<object, string> list = new Dictionary<object, string>();
        public string Name
        {
            get
            {
                if (list.ContainsKey(this.GetHashCode()))
                    return list[this.GetHashCode()];
                return _name;
            }
            set
            {
                list[this.GetHashCode()] = value;
            }
        }
    }
    测试代码
    public static void Test2()
    {
        List<People> list = new List<People>();
        for (int i = 0; i < 10000; i++)
        {
            var entity = new People();
            if (i<10)
            {
                entity.Name = i.ToString();
            }
            list.Add(entity);
        }
    }

    image

    依赖对象共享依赖属性

    下面我们来看下WPF元素的依赖属性,我们可以来比较下两个不同对象的属性元数据,返回的结果是相同,也说明了其内部机制也是如此,也是为了节省内存.

    Object.ReferenceEquals(Button.BackgroundProperty.GetMetadata(button1),
                           Button.BackgroundProperty.GetMetadata(button2));

    比较两个对象的属性,依然是相同,因为返回的是默认值

    Object.ReferenceEquals(button1.Background, button2.Background);

    然而为了节省内存,真的有必要这么做吗?这太麻烦了.

    我们知道WPF控件继承而来的属性有一大片,密密麻麻,当我们布局的的时候窗体上往往有着很多的元素,如下截图.如果一个对象以50个属性(其实远远不止)来计算,那么也是一笔不小的开销,如果说依赖属性一开始的动机是为了节省内存,实质上其内部功能已经远远不是节省内存这么简单了.下篇继续

    image

  • 相关阅读:
    Spark的协同过滤.Vs.Hadoop MR
    IAAS: IT公司去IOE-Alibaba系统构架解读
    八种Docker容器开发模式解析
    Docker的特性解析
    Docker的官网在线--中文教程
    三维重建:深度相机方案对比-KinectFusion的基本原理(尺度)
    ES: 机器学习、专家系统、控制系统的数学映射
    算法设计之—常用算法之-分支界定法
    图像特征综述
    CaptCha的现状与未来
  • 原文地址:https://www.cnblogs.com/Clingingboy/p/1756292.html
Copyright © 2020-2023  润新知