C#基础 延迟加载介绍与实例
延迟加载(lazy loading) 设计模式是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据(读取属性值)的时候,才真正执行数据加载操作.
为了便于理解, 我们来建立一个场景, 假设我们要构造一个hero(英雄) 类, 每个hero 有自己的名字和(specialskill)特殊技能.
建模
这是一种建立的方法:
public class hero
{
public string fullname { get; set; }
public string name { get; set; }
public specialskill skill{ get; set; }
public hero(string name)
{
name = name;
fullname = "super " + name;
skill = new specialskill(name);
}
}
public class specialskill
{
public int power { get; set; }
public string skillname { get; set; }
public int strengthspent { get; set; }
public specialskill(string name)
{
console.writeline("loading special skill .....");
power = name.length;
strengthspent = name.length * 3;
skillname = name + " blazing";
console.writeline(skillname + ",... this's what makes a legend!");
}
}
class program
{
static void main(string[] args)
{
hero hero = new hero("wukong");
console.writeline("\n\n.......................press enter to continue.......................\n\n");
console.read();
console.writeline("hero's special skill: " + hero.skill.skillname);
console.read();
console.read();
}
}
运行程序后输出如下, 这个例子非常的容易理解, 结果也是显然的.
它的缺点是, 当运行hero 构造函数的时候, specialskill 的所有属性都已经加载了. 如果我们只想获取这个hero 的fullname, 我们也加载了specialskill 所有值.
属性的加载延迟
在没有lazy<t> 以前我们可以这样做:
public class hero
{
public string fullname { get; set; }
public string name { get; set; }
private specialskill skill;
public specialskill skill
{
get { return skill ?? (skill = new specialskill(name)); }
}
public hero(string name)
{
name = name;
fullname = "super " + name;
}
}
即: 修改属性specialskill的加载方法. 那么当我们再运行程序时, 得到的输出就是:
非常好! 这就是我们要的效果, 这样可以让系统更加的有效率.
lazy<t>
当net framework 引入了lazy<t> 类后, 我们也可以使用它来实现:
public class hero
{
public string fullname { get; set; }
public string name { get; set; }
private readonly lazy<specialskill> skill;
public specialskill skill
{
get { return skill.value; }
}
public hero(string name)
{
name = name;
fullname = "super " + name;
skill = new lazy<specialskill>(() => new specialskill(name));
}
}
lazy<t>提供对延迟初始化的支持。而 lazy<t> 中的一个属性 value, 则是获取当前 lazy<t> 实例的延迟初始化值。
lazy<t>的优势
那么既然我们已经可以用属性缓存的方法实现, 为什么还要引入lazy<t> ?
至少lazy<t> 有以下几点优势:
它具有 lazythreadsafetymode, 但是我们一般不使用它, 除非是很关键的情况下(在此略去181个字)
它使属性的定义行更加简单
从语义上来讲, 它更加明确, 更加具有可读性
它允许null为有效值
推荐阅读
-
C#基础 延迟加载介绍与实例
-
PHP命名空间与自动加载机制的基础介绍
-
C#基础(203)实例方法和重载方法总结,构造方法与实例方法总结,this关键字
-
mybatis基础系列(四)——关联查询、延迟加载、一级缓存与二级缓存
-
PHP命名空间与自动加载机制的基础介绍
-
JavaScript基础篇之变量作用域、传值、传址的简单介绍与实例_javascript技巧
-
JavaScript基础篇之变量作用域、传值、传址的简单介绍与实例_javascript技巧
-
C#根据表格偶数与奇数加载不同颜色的实例分析
-
C#基础(203)实例方法和重载方法总结,构造方法与实例方法总结,this关键字
-
mybatis基础系列(四)——关联查询、延迟加载、一级缓存与二级缓存