本文来自:http://kb.cnblogs.com/page/99182/

作者: 杨延成  来源: 博客园  发布时间: 2011-05-01 15:06  阅读: 4662 次  推荐: 0   原文链接   [收藏]

  延迟加载,亦称延迟实例化,延迟初始化等,主要表达的思想是,把对象的创建将会延迟到使用时创建,而不是在对象实例化时创建对象,即用时才加载。这种方式有助于提高于应用程序的性能,避免浪费计算,节省内存的使用等。针对于这种做法,似乎称之为即用即创建更为合适些。

  先来看一下在Framework4.0中如何实现延迟加载。

  Framework4.0提供了一个包装类 Lazy<T>,可以轻松的实现延迟加载。

///这行代码表明:要创建一个延迟加载的字符串对象s
///原型为Lazy<T> 对象名=new Lazy<T>(Fun<T>)
///采用泛型委托进行构造,实例化此委托时要求必须是返回值T类型的方法
///如在本例中,T为string,则TestLazy.GetString方法的返回值必须也是string类型
Lazy<string> s = new Lazy<string>(TestLazy.GetString);

  本例中TestLazy.GetString()方法如下示:

public class TestLazy
{
public static string GetString()
{
return DateTime.Now.ToLongTimeString();
}
}

  可以通过IsValueCreated属性来确定对象是否已创建,通过Value属性来获取当前对象的值。

Console.WriteLine(s.IsValueCreated);//返回False
Console.WriteLine(s.Value); //返回s的当前值
Console.WriteLine(s.IsValueCreated);//返回True

  下面经出完整代码,以供测试:

  字符串对象延迟加载完整示例:

class Program
{
static void Main(string[] args)
{
///这行代码表明:要创建一个延迟加载的字符串对象s
///原型为Lazy<T> 对象名=new Lazy<T>(Fun<T>)
///采用泛型委托进行构造,实例化此委托时要求必须是返回值T类型的方法
///如在本例中,T为string,则TestLazy.GetString方法的返回值必须也是string类型
Lazy<string> s = new Lazy<string>(TestLazy.GetString);
Console.WriteLine(s.IsValueCreated);//返回False
Console.WriteLine(s.Value); //返回S的当前值
Console.WriteLine(s.IsValueCreated);//返回True
}
}
public class TestLazy
{
public static string GetString()
{
return DateTime.Now.ToLongTimeString();
}
}

  下面再用一个例子,演示延迟加载。

  在这个例子中,使用了BlogUser对象,该对象包含多个Article对象,当加载BlogUser对象时,Article对象并不加载,当需要使用Article对象时,才加载。

  包含子对象的延迟加载

class Program
{
static void Main(string[] args)
{
BlogUser blogUser = new BlogUser(1);
Console.WriteLine("blogUser has been initialized"); foreach (var article in blogUser.Articles.Value)
{
Console.WriteLine(article.Title);
}
}
} public class BlogUser
{
public int Id { get; private set; }
public Lazy<List<Article>> Articles { get; private set; }
public BlogUser(int id)
{
this.Id = id;
Articles =new Lazy<List<Article>>(()=>ArticleServices.GetArticesByID(id));
Console.WriteLine("BlogUser Initializer");
}
}
public class Article
{
public int Id { get; set; }
public string Title{get;set;}
public DateTime PublishDate { get; set; }
}
public class ArticleServices
{
public static List<Article> GetArticesByID(int blogUserID)
{
List<Article> articles = new List<Article> {
new Article{Id=1,Title="Lazy Load",PublishDate=DateTime.Parse("2011-4-20")},
new Article{Id=2,Title="Delegate",PublishDate=DateTime.Parse("2011-4-21")},
new Article{Id=3,Title="Event",PublishDate=DateTime.Parse("2011-4-22")},
new Article{Id=4,Title="Thread",PublishDate=DateTime.Parse("2011-4-23")}
};
Console.WriteLine("Article Initalizer");
return articles;
}
}

  运行结果如图示:

aaarticlea/png;base64,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" alt="" />

  最后说一下,延迟加载主要应用场景:

  当创建一个对象的子对象开销比较大时,而且有可能在程序中用不到这个子对象,那么可以考虑用延迟加载的方式来创建子对象。另外一种情况就是当程序一启动时,需要创建多个对象,但仅有几个对象需要立即使用,这样就可以将一些不必要的初始化工作延迟到使用时,这样可以非常有效的提高程序的启动速度。

  这种技术在ORM框架得到了广泛应用,也并非C#独有的,比如Java里的Hibernate框架也使用了这一技术。

C# 基础概念之延迟加载的更多相关文章

  1. 【Machine Learning】机器学习及其基础概念简介

    机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

  2. TCP/IP基础概念及通信过程举例

    TCP/IP基础概念及通信过程举例 出现 上个世纪60年代,由于中央集中式网络的容灾性较弱,以美国国防部为中心的一家组织研究出分组交换网络.后来为了验证分组交换技术的实用性,ARPANET出现了,并且 ...

  3. Jmeter基础之---jmeter基础概念

    Jmeter基础之---jmeter基础概念 JMeter 介绍: 一个非常优秀的开源的性能测试工具. 优点:你用着用着就会发现它的重多优点,当然不足点也会呈现出来. JMeter 介绍: 一个非常优 ...

  4. 快速入门系列--WCF--01基础概念

    转眼微软的WCF已走过十个年头,它是微软通信框架的集大成者,将之前微软所有的通信框架进行了整合,提供了统一的应用方式.记得从自己最开始做MFC时,就使用过Named Pipe命名管道,之后做Winfo ...

  5. 理解 angular2 基础概念和结构 ----angular2系列(二)

    前言: angular2官方将框架按以下结构划分: Module Component Template Metadata Data Binding Directive Service Dependen ...

  6. JavaBean 基础概念、使用实例及代码分析

    JavaBean 基础概念.使用实例及代码分析 JavaBean的概念 JavaBean是一种可重复使用的.且跨平台的软件组件. JavaBean可分为两种:一种是有用户界面的(有UI的):另一种是没 ...

  7. RabbitMQ基础概念详细介绍

    http://blog.csdn.net/column/details/rabbitmq.html 转至:http://www.ostest.cn/archives/497 引言 你是否遇到过两个(多 ...

  8. linux设备驱动归纳总结(二):模块的相关基础概念【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-59415.html linux设备驱动归纳总结(二):模块的相关基础概念 系统平台:Ubuntu 10 ...

  9. linux设备驱动归纳总结(一)内核的相关基础概念【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-59413.html linux设备驱动归纳总结(一):内核的相关基础概念 xxxxxxxxxxxxxx ...

随机推荐

  1. (转)mysql分表的3种方法

    原文:http://blog.51yip.com/mysql/949.html 一,先说一下为什么要分表 当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿 ...

  2. 认识Ant

    Ant是一个Apache基金会下的跨平台的构件工具,它可以实现项目的自动构建和部署等功能.在本文中,主要让读者熟悉怎样将Ant应用到Java项目中,让它简化构建和部署操作. 一.            ...

  3. sql执行顺序整理

    sql的执行顺序,是优化sql语句执行效率必须要掌握的.各个数据库可能有细小的差别,但大体顺序是相同的,这里只做大致说明. 一.总体执行顺序 在sql语句执行之前,还有SQL语句准备执行阶段,这里不做 ...

  4. HashMap的使用方法及注意事项

    99.Map(映射):Map 的keySet()方法会返回 key 的集合,因为 Map 的键是不能重复的,因此 keySet()方法的返回类型是 Set:而 Map 的值是可以重复的,因此 valu ...

  5. 安卓Menu键的问题

    近期开发中有须要Menu键,结果发现了一个非常尴尬的问题.我的測试机上有Menu键.可是測试平板上没有,队友的測试机上竟然也没有Menu键.这着实有些尴尬... 上网谷歌之后才发现问题所在: 仅仅有在 ...

  6. 对于Android Service 生命周期进行全解析

    应用程序组件有一个生命周期——一开始Android实例化他们响应意图,直到结束实例被销毁.在这期间,他们有时候处于激活状态,有时候处于非激 活状态:对于活动,对用户有时候可见,有时候不可见.组件生命周 ...

  7. react-native使用react-art制作SVG动画

    想要使用SVG做一个动画,郁闷了一上午终于有了一点思路.. 其实我是看了一篇国外的文章.网址:http://browniefed.com/blog/2015/05/03/getting-react-a ...

  8. TextField详细用法

    http://www.cnblogs.com/VincentXue/archive/2012/08/28/2660001.html

  9. IOS 中关于自定义Cell 上的按钮 开关等点击事件的实现方法(代理)

    1.在自定义的Cell .h文件中写出代理,写出代理方法. @protocol selectButtonDelegate <NSObject> -(void)selectModelID:( ...

  10. CSS 设计彻底研究(五)文字与图像

    第五章 文字与图像 5.1.2 设置字体 通过font-family属性设置字体.可以声明多种字体,字体之间用逗号分隔开.如一些字体名称中间有空格,需用双引号将其引起来,使浏览器知道这是一种字体的名称 ...