延迟加载(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> 有以下几点优势:

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

不可不知的C#基础 4. 延迟加载 -- 提高性能的更多相关文章

  1. ASP.NET MVC之如何看待内置配置来提高性能优化(四)

    前言 前几篇我们比较基础的讲了下MVC中的知识,这一节我们穿插点知识,讲讲MVC中我们可以提高性能的办法. Razor视图引擎优化(优化一) 我们知道默认情况下配置MVC去解析一个视图会首先约定通过查 ...

  2. CSS性能分析,如何优化CSS提高性能

    不负十年后的自己,共勉! 前端性能优化一直是一个比较热门的话题,我们总是在尽我们最大的努力去,提高我们的页面性能,比如减少HTTP请求,利用工具对资源进行合并压缩,脚本置底,避免重复请求,css sp ...

  3. SQL Server 性能优化之——系统化方法提高性能

    SQL Server 性能优化之——系统化方法提高性能 阅读导航 1. 概述 2. 规范逻辑数据库设计 3. 使用高效索引设计 4. 使用高效的查询设计 5. 使用技术分析低性能 6. 总结 1. 概 ...

  4. 使用SQL Server 2000索引视图提高性能

    什么是索引视图? 许多年来,Microsoft? SQL Server? 一直都提供创建虚拟表(称为视图)的功能.在过去,这些视图主要有两种用途: 提供安全机制,将用户限制在一个或多个基表中的数据的某 ...

  5. EF提高性能

    实体框架 5 性能注意事项 作者:David Obando.Eric Dettinger 等 发布时间:2012 年 4 月 1.简介 对象关系映射框架是一种在面向对象的应用程序中提供数据访问抽象的便 ...

  6. 千万级MySQL数据库建立索引,提高性能的秘诀

    实践中如何优化MySQL 实践中,MySQL的优化主要涉及SQL语句及索引的优化.数据表结构的优化.系统配置的优化和硬件的优化四个方面,如下图所示: SQL语句及索引的优化 SQL语句的优化 SQL语 ...

  7. 对于大批量赋值功能,使用if判断是否能提高性能

    场景: 如果对某变量进行赋值,是否需要判断一下,如果相等就不用赋值,这样会不会提高性能. 代码如下: "; "; , x2=, x3=; Stopwatch w = new Sto ...

  8. Java编程提高性能时需注意的地方

    1.尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面 第一,控制资源的使用,通过线程同步来控制资 ...

  9. 使用C# yield关键字来提高性能和可读性

    对于”yield”这个关键字我已经见过N次了,直到最近我才知道这个关键字所蕴含的力量.我将在下面展示出一些使用”yield”让你的代码有更高可读性和更好性能的例子. 为了让你对yield有一些快速概览 ...

随机推荐

  1. 分享git的常用命令

    Git操作笔记       1.创建目录         $ mkdir learngit         $ cd learngit       2.把新建的目录变成仓库         $ git ...

  2. Effective Java 39 Make defensive copies when needed

    Principle It is essential to make a defensive copy of each mutable parameter to the constructor. Def ...

  3. Angular动态注册组件(controller,service...)

    使用angular的场景一般是应用类网站 这也意味着会有很多的controller,service,directive等等 正常情况下我们要把这些内容一次性下载并注册,由于文件较多,对首次加载的效率影 ...

  4. node中简单scoket介绍

    /*socket.io是一个基于 node.js 的项目,其主要作用是将WebScoket 协议应用到所有的浏览器.该模块主要应用于实时的长连接 多请求的项目中,例如在线联网游戏中.实时聊天.实施股票 ...

  5. 深入理解spring中的各种注解

    Spring中的注解大概可以分为两大类: 1)spring的bean容器相关的注解,或者说bean工厂相关的注解: 2)springmvc相关的注解. spring的bean容器相关的注解,先后有:@ ...

  6. nginx入门(安装,启动,关闭,信号量控制)

    公司使用到了nginx,于是周末初步接触了一下nginx,立即被其简洁,优雅,高效的特性给迷住了.nginx是在是个好东西,配置极其简单,容易理解,极其高效,稍微一调优,ab测试10k并发,很轻松.比 ...

  7. ehcache整合spring本地接口方式

    一.简介 ehcache整合spring,可以通过使用echache的本地接口,从而达到定制的目的.在方法中根据业务逻辑进行判断,从缓存中获取数据或将数据保存到缓存.这样让程序变得更加灵活. 本例子使 ...

  8. 数据结构--栈的应用(表达式求值 nyoj 35)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=35 题目: 表达式求值 时间限制:3000 ms | 内存限制:65535 KB描述 AC ...

  9. linux硬链接与软链接

    在linux操作系统中的文件数据除了实际的内容外,还会含有文件权限(rwx)与文件属性(owner,group,other等),文件系统通常会将这两部分的数据存放在不同的区块,文件权限与文件属性放置在 ...

  10. phpcms v9 下拉菜单 二级 三级子栏目调用方法

    很多网站的导航栏可以实现下拉二级菜单,三级菜单等效果,今天我们就来分享phpcms v9 支持下拉菜单的方法,可以支持无限子栏目调用,具体写法如下: <ul> {pc:content ac ...