• C#中的延迟加载


    什么是延迟加载?  

      延迟加载顾名思义就是:推迟加载的时机,当真正使用的时候才加载

      通常在创建一个大对象时,有些属性我们可以在使用到的时候才去创建(设置属性的值),这个可以有效的提升系统性能。  

    示例:

    //定义了一个Hero类型
    public class Hero
    {
        public string Name{get;set;}
        
        public string FullName{get;set;}
        
        public Skill objSkill;
        
        public Hero(string name)
        {
            Name=name;
            FullName="Super "+name;
            objSkill=new Skill(name);
        }
    }
    
    //定义一个Skill类型
    public class Skill
    {
        public string Name{get;set;}
        
        public int Power{get;set;}
        
        public Skill(string name)
        {
            Name=name;
            Power=name.Length;
        }
    }
    
    
    public class Program
    {
        public static void Main(string[] args)
        {
            Hero hero=new Hero("qi da sheng");
            //此时我只想获取Hero的FullName,但是同时调用Skill的构造方法,加载了Skill的属性,
            //初始化Skill需要在内存中开辟一定的空间,造成没必要的空间浪费
            Console.WriteLine(hero.FullName);
            
            //思考:如果实现在调用Skill.Name的时候才去真正创建Skill对象呢?
        }
    }
    View Code

    改进一

    改进一:
    //定义了一个Hero类型
    public class Hero
    {
        public string Name{get;set;}
        
        public string FullName{get;set;}
        
        //public Skill objSkill;
        private Skill _skill;
        
        public Skill objSkill
        {
            get {return _skill??(new _skill(Name));}
        }
        
        public Hero(string name)
        {
            Name=name;
            FullName="Super "+name;
            //objSkill=new Skill(name);
        }
    }
    
    //定义一个Skill类型
    public class Skill
    {
        public string Name{get;set;}
        
        public int Power{get;set;}
        
        public Skill(string name)
        {
            Name=name;
            Power=name.Length;
        }
    }
    
    
    public class Program
    {
        public static void Main(string[] args)
        {
            Hero hero=new Hero("qi da sheng");
            //此时获取Hero的FullName时并不会去创建Skill的实例
            Console.WriteLine(hero.FullName);
            //真正用到Skill.Name时才会创建Skill的实例,从而实现了延迟加载效果?
            Console.WriteLine(hero.ObjSkill.Power);
            
            //思考2:有没有其他更好的方法?
        }
    }
    View Code

    改进二

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Demo_Lazy
    {
        //定义了一个Hero类型
        public class Hero
        {
            public string Name { get; set; }
    
            public string FullName { get; set; }
    
            private readonly Lazy<Skill> skill;
    
            public Skill objSkill
            {
                get { return skill.Value; }
            }
    
            public Hero(string name)
            {
                Name = name;
                FullName = "Super " + name;
                skill = new Lazy<Skill>(() => new Skill(Name));
            }
        }
    
        //定义一个Skill类型
        public class Skill
        {
            public string Name { get; set; }
    
            public int Power { get; set; }
    
            public Skill(string name)
            {
                Name = name;
                Power = name.Length;
            }
        }
    
    
        public class Program
        {
            public static void Main(string[] args)
            {
                Hero hero = new Hero("qi da sheng");
                //此时获取Hero的FullName时并不会去创建Skill的实例
                Console.WriteLine(hero.FullName);
                //真正用到Skill.Name时才会创建Skill的实例,从而实现了延迟加载效果
                Console.WriteLine(hero.objSkill.Power);
    
                Console.Read();
            }
        }
    
    
    }
    View Code

    Lazy<T>的优势

    那么既然我们已经可以用属性缓存的方法实现, 为什么还要引入Lazy<T> ?

    至少Lazy<T> 有以下几点优势:

    1. 它具有 LazyThreadSafetyMode, 但是我们一般不使用它, 除非是很关键的情况下(在此略去181个字) 
    2. 它使属性的定义行更加简单 
    3. 从语义上来讲, 它更加明确, 更加具有可读性 
    4. 它允许null为有效值

    参考:

    http://www.cnblogs.com/multiplesoftware/archive/2011/11/24/2261105.html

    https://msdn.microsoft.com/en-us/library/dd642331(v=vs.110).aspx

  • 相关阅读:
    Android开发学习之路-使用Handler和Message更新UI
    Android开发学习之路-Service和Activity的通信
    Android开发学习之路-自定义ListView(继承BaseAdapter)
    URI、URL、URN
    理解 node.js 的事件循环
    创建hexo风格的markdown页面
    heroku
    js通过沿着作用域链还是原型链查找变量
    浏览器中实现3D全景浏览
    数据可视化图表ECharts
  • 原文地址:https://www.cnblogs.com/qianxingdewoniu/p/5654287.html
Copyright © 2020-2023  润新知