ASP.NET泛型四之使用Lazy<T>实现延迟加载_实用技巧

来源:脚本之家  责任编辑:小易  

".NET泛型"系列:

ASP.NET泛型一之泛型简介与基本语法

ASP.NET泛型二之泛型的使用方法

ASP.NET泛型三之使用协变和逆变实现类型转换

ASP.NET泛型四之使用Lazy<T>实现延迟加载

对于一些"大对象"的创建,我们常常希望延迟加载,即在需要的时候再创建对象实例。现在Lazy<T>很好地支持了这一特点。主要包括:

没有Lazy<T>之前

在没有Lazy<T>之前,我们通过如下方式实现延迟加载。

public class LazySinleton
{
    private LazySingleton()
    {}
 
    public static LazySingleton Instance
    {
        get
        {
            return Lazy.data;
        }
    }
 
    private class Lazy
    {
        static Lazy()
        {}
 
        internal static readonly LazySingleton data = new LazySingleton();
    }
}

以上

通过私有构造函数屏蔽了LazySingleton类通过构造函数创建的方式私有嵌套类Lazy的data字段负责提供一个LazySingleton的实例只能通过LazySingleton的属性Instance,才能拿到内部类Lazy.data所代表的实例

Lazy<T>实例

先看Lazy<T>的定义:

public class Lazy<T>
{
    public Lazy();
    public Lazy(bool isThreadSafe);
    public Lazy(Func<T> valueFactory);
    public Lazy(LazyThreadSafeMode mode);
    public Lazy(Func<T> valueFactory, bool isThreadSafe);
    public Lazy(Funct<T> valueFactory, LazyThreadSafetyMode mode);

    public bool IsValueCreated{get;}
    public T Value {get;}
    public override string ToStirng();
}

通过Lazy<T>的构造函数重载创建对象,再通过体现延迟加载的Value属性来实现对象的创建,并获取对象实例。

public class SomeClass
{
    public int ID{get;set;}
}

Lazy<SomeClass> temp = new Lazy<SomeClass>();
Console.WriteLine(temp.Value.ID);

以上,只适用于没有构造函数的情况,如果有构造函数如何处理呢?
--使用public Lazy(Func<T> valueFactory),通过委托创建对象

pubic class SomeClass
{
    public int ID{get;set;}
    public SomeClass(int id)
    {
        this.ID = id;
    }
}

Lazy<SomeClass> temp = new Lazy<SomeClass>(() => new Big(100));
Console.WriteLine(temp.Value.ID);

延迟加载的本质

创建自定义延迟加载类。

    public class MyLazy<T>
    {
        private volatile object boxed; //volatile说明在多线程状况下,也可以修改该字段
        private Func<T> valueFactory; //委托,用来生产T对象实例

        static MyLazy(){}
        public MyLazy(){}

        public MyLazy(Func<T> valueFactory)
        {
            this.valueFactory = valueFactory;
        }

        public T Value
        {
            get
            {
                Boxed boxed = null;
                if (this.boxed != null)
                {
                    boxed = this.boxed as Boxed;
                    if (boxed != null)
                    {
                        return boxed.value;
                    }
                }
                return this.Init();
            }
        }

        //初始化对象实例
        private T Init()
        {
            Boxed boxed = null;
            if (this.boxed == null)
            {
                boxed = this.CreateValue();
                this.boxed = boxed;
            }
            return boxed.value;
        }

        //创建内部类实例
        private Boxed CreateValue()
        {
            //如果创建对象实例的委托valueFactory存在
            if (this.valueFactory != null)
            {
                //就通过委托生成对象实例
                return new Boxed(this.valueFactory());
            }
            else
            {
                //否则,通过反射生成对象实例
                return new Boxed((T)Activator.CreateInstance(typeof(T)));
            }
        }

        //内部嵌套类,通过构造函数对其字段赋值
        private class Boxed
        {
            internal T value;
            internal Boxed(T value)
            {
                this.value = value;
            }
        }
    }

自定义带构造函数的类。

    public class Big
    {
        public int ID { get; set; }
        public Big(int id)
        {
            this.ID = id;
        }
    }

自定义创建对象实例的工厂类。

    public class BigFactory
    {
        public static Big Build()
        {
            return new Big(10);
        }
    }

客户端调用。

    class Program
    {
        static void Main(string[] args)
        {
            MyLazy<Big> temp = new MyLazy<Big>(() => BigFactory.Build());
            Console.WriteLine(temp.Value.ID);
            Console.ReadKey();
        }
    }

延迟加载的本质大致是:

由延迟加载类的内部嵌套类产生对象实例再通过延迟加载类的某个属性来延迟获取对象实例,而对象实例是通过委托等方式创建的

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对真格学网的支持。如果你想了解更多相关内容请查看下面相关链接

您可能感兴趣的文章:ASP.NET泛型三之使用协变和逆变实现类型转换ASP.NET泛型二之泛型的使用方法ASP.NET泛型一之泛型简介与基本语法

  • 本文相关:
  • asp.net core web app应用第三方bootstrap模板的方法教程
  • c#处理json的另外一种方式成功实践
  • 查看json输出的*最方便*的方法 (转)
  • 关于c#中datetime常用方法概述
  • .net core动态调用泛型方法详解
  • asp.net中的几种弹出框提示基本实现方法
  • 记录asp.net网站是什么原因导致停止运行的代码
  • asp.net下遍历页面中所有的指定控件的代码
  • cookies的各方面知识(基础/高级)深度了解
  • aspx中页面按钮写返回上一页代码
  • 如何对绑定泛型数据的GridView排序呢? ASP.NET
  • 关于使用泛型的问题(***.net)
  • 使用.Net2.0的泛型功能编写一个通用的取最大值的方法? 函数原...
  • .NET 关于泛型的协变和逆变中 in / out 两个参数(或者方法) 的...
  • 求***.NET泛型数据传递实例
  • ***.net 泛型 组合应用
  • .NET泛型中的协变与逆变 是什么意思?
  • .net MVC 泛型类 绑定到 html.dropdownlist
  • ***.net返回泛型数组
  • .net MVC 泛型类 绑定到 html.dropdownlist
  • .net MVC 泛型类 绑定到 html.dropdownlist
  • .NET中 泛型抽象类怎样实现多态
  • 为什么.net要引入泛型,委托和linq
  • ***.net c# 定义泛型,实体各实体层! 如何更新,添加,删除数据库的...
  • .net中,泛型集合有哪几种?
  • 网站首页网页制作脚本下载服务器操作系统网站运营平面设计媒体动画电脑基础硬件教程网络安全基础应用实用技巧自学过程首页asp.net实用技巧asp.net泛型三之使用协变和逆变实现类型转换asp.net泛型二之泛型的使用方法asp.net泛型一之泛型简介与基本语法asp.net core web app应用第三方bootstrap模板的方法教程c#处理json的另外一种方式成功实践查看json输出的*最方便*的方法 (转)关于c#中datetime常用方法概述.net core动态调用泛型方法详解asp.net中的几种弹出框提示基本实现方法记录asp.net网站是什么原因导致停止运行的代码asp.net下遍历页面中所有的指定控件的代码cookies的各方面知识(基础/高级)深度了解aspx中页面按钮写返回上一页代码未将对象引用设置到对象的实例 (system.nullrefjava正则表达式 pattern和matcherasp.net(c#)网页跳转七种方法小结未能加载文件或程序集“xxx”或它的某一个依赖项。试图加载格asp.net中的几种弹出框提示基本实现方法asp.net“服务器应用程序不可用” 解决方法asp.net gridview 72般绝技asp.net生成excel并导出下载五种实现方法system.runtime.interopservicesasp.net对路径"xxxxx"的访问asp.net在事件中启动线程来打开一个页面的实现方法asp.net保持页面滚动条位置(页面提交后不变)[c#]asp.ent下开发中tag的开发技巧asp.net检查服务器上目录或文件是否存在的方法.net core下使用kafka的方法步骤详解asp.net mvc——控制器与动作(controller and a.netcore获取json和xml格式的配置信息.net实现websocket服务端即时通信实例asp.net实现数据从datatable导入到excel文件并创建表的方法asp.net 在下载文件时对其重命名的思路及实现方法
    免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved