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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM