什么是延遲加載?
延遲加載顧名思義就是:推遲加載的時機,當真正使用的時候才加載。
通常在創建一個大對象時,有些屬性我們可以在使用到的時候才去創建(設置屬性的值),這個可以有效的提升系統性能。
示例:

//定義了一個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對象呢? } }
改進一

改進一: //定義了一個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:有沒有其他更好的方法? } }
改進二

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(); } } }
Lazy<T>的優勢
那么既然我們已經可以用屬性緩存的方法實現, 為什么還要引入Lazy<T> ?
至少Lazy<T> 有以下幾點優勢:
- 它具有 LazyThreadSafetyMode, 但是我們一般不使用它, 除非是很關鍵的情況下(在此略去181個字)
- 它使屬性的定義行更加簡單
- 從語義上來講, 它更加明確, 更加具有可讀性
- 它允許null為有效值
參考:
http://www.cnblogs.com/multiplesoftware/archive/2011/11/24/2261105.html
https://msdn.microsoft.com/en-us/library/dd642331(v=vs.110).aspx