搜索

查看: 3104|回复: 11

[ASP.NET] ASP.NET泛型四之使用Lazy实现延迟加载

[复制链接]
发表于 2023-5-4 11:32:54 | 显示全部楼层 |阅读模式
Editor 2023-5-4 11:32:54 3104 11 看全部
".NET泛型"系列:
ASP.NET泛型一之泛型简介与基本语法
ASP.NET泛型二之泛型的使用方法
ASP.NET泛型三之使用协变和逆变实现类型转换
ASP.NET泛型四之使用Lazy实现延迟加载
对于一些"大对象"的创建,我们常常希望延迟加载,即在需要的时候再创建对象实例。现在Lazy很好地支持了这一特点。主要包括:
没有Lazy之前
在没有Lazy之前,我们通过如下方式实现延迟加载。
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实例
    先看Lazy的定义:
    public class Lazy
    {
        public Lazy();
        public Lazy(bool isThreadSafe);
        public Lazy(Func valueFactory);
        public Lazy(LazyThreadSafeMode mode);
        public Lazy(Func valueFactory, bool isThreadSafe);
        public Lazy(Funct valueFactory, LazyThreadSafetyMode mode);
        public bool IsValueCreated{get;}
        public T Value {get;}
        public override string ToStirng();
    }
    通过Lazy的构造函数重载创建对象,再通过体现延迟加载的Value属性来实现对象的创建,并获取对象实例。
    public class SomeClass
    {
        public int ID{get;set;}
    }
    Lazy temp = new Lazy();
    Console.WriteLine(temp.Value.ID);
    以上,只适用于没有构造函数的情况,如果有构造函数如何处理呢?
    --使用public Lazy(Func valueFactory),通过委托创建对象
    pubic class SomeClass
    {
        public int ID{get;set;}
        public SomeClass(int id)
        {
            this.ID = id;
        }
    }
    Lazy temp = new Lazy(() => new Big(100));
    Console.WriteLine(temp.Value.ID);
    延迟加载的本质
    创建自定义延迟加载类。
        public class MyLazy
        {
            private volatile object boxed; //volatile说明在多线程状况下,也可以修改该字段
            private Func valueFactory; //委托,用来生产T对象实例
            static MyLazy(){}
            public MyLazy(){}
            public MyLazy(Func 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[B] temp = new MyLazy[B](() => BigFactory.Build());
                Console.WriteLine(temp.Value.ID);
                Console.ReadKey();
            }
        }
    延迟加载的本质大致是:
  • 由延迟加载类的内部嵌套类产生对象实例
  • 再通过延迟加载类的某个属性来延迟获取对象实例,而对象实例是通过委托等方式创建的
    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对知鸟论坛的支持。如果你想了解更多相关内容请查看下面相关链接
  • 回复

    使用道具 举报

    发表于 2023-6-28 22:44:12 | 显示全部楼层
    无人岛屿颈 2023-6-28 22:44:12 看全部
    感谢楼主的无私分享!要想知鸟论坛好 就靠你我他
    回复

    使用道具 举报

    发表于 2023-6-29 17:20:47 | 显示全部楼层
    小妖花满楼满fx 2023-6-29 17:20:47 看全部
    感谢楼主的无私分享!要想知鸟论坛好 就靠你我他
    回复

    使用道具 举报

    发表于 2023-6-29 22:28:16 | 显示全部楼层
    戏做顿 2023-6-29 22:28:16 看全部
    论坛不能没有像楼主这样的人才啊!我会一直支持知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-29 23:45:07 | 显示全部楼层
    术数古籍专卖疤 2023-6-29 23:45:07 看全部
    这东西我收了!谢谢楼主!知鸟论坛真好!
    回复

    使用道具 举报

    发表于 2023-6-30 03:02:39 | 显示全部楼层
    123456819 2023-6-30 03:02:39 看全部
    楼主发贴辛苦了,谢谢楼主分享!我觉得知鸟论坛是注册对了!
    回复

    使用道具 举报

    发表于 2023-6-30 19:54:01 | 显示全部楼层
    知足常乐77 2023-6-30 19:54:01 看全部
    楼主,我太崇拜你了!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-7-3 08:28:37 | 显示全部楼层
    尘埃416 2023-7-3 08:28:37 看全部
    楼主,我太崇拜你了!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-7-3 17:21:42 | 显示全部楼层
    当当当当裤裆坦 2023-7-3 17:21:42 看全部
    其实我一直觉得楼主的品味不错!呵呵!知鸟论坛太棒了!
    回复

    使用道具 举报

    发表于 2023-7-6 05:22:38 | 显示全部楼层
    123456809 2023-7-6 05:22:38 看全部
    楼主,我太崇拜你了!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    • 您可能感兴趣
    点击右侧快捷回复 【请勿灌水】
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则 返回列表

    RSS订阅| SiteMap| 小黑屋| 知鸟论坛
    联系邮箱E-mail:zniao@foxmail.com
    快速回复 返回顶部 返回列表