太原首页推广,搜索引擎优化的简写是,wordpress当前文章所属分类,高校建设主流的校园网站【.NET Core】Lazy 实现延迟加载详解 文章目录 【.NET Core】LazyT 实现延迟加载详解一、概述二、LazyT是什么三、Lazy基本用法3.1 构造时使用默认的初始化方式3.2 构造时使用指定的委托初始化 四、Lazy.Value使用五、Lazy扩展用法5.1 实现延迟属性5.2 Lazy实现…【.NET Core】Lazy 实现延迟加载详解 文章目录 【.NET Core】LazyT 实现延迟加载详解一、概述二、LazyT是什么三、Lazy基本用法3.1 构造时使用默认的初始化方式3.2 构造时使用指定的委托初始化 四、Lazy.Value使用五、Lazy扩展用法5.1 实现延迟属性5.2 Lazy实现惰性加载单例模式 六、Lazy常用扩展方法 一、概述
延迟初始化是一种将对象的创建延迟到第一次需要用时的技术。简而言之就是对象的初始化发生在第一次需要调用的时候执行。通常所说的延迟初始化和延迟实例化的意思是相同。通过使用延迟基础可以避免应用程序不必要的计算和内存消耗。
从.NET 4.0开始可以使用Lazy来实现对象的延迟初始化从而优化系统的性能。延迟初始化就是将对象的初始化延迟到第一次使用该对象时。延迟初始化是我们优化程序性能的一种方式。如创建一个对象时需要花费很大的开销而这一对象在系统运行过程中不一定会用到这时就可以使用延迟初始化在第一次使用该对象时再对其进行实例化。如果没有用在整个应用程序生命期则不需要初始化使用延迟初始化可以提高程序的利用率从而使程序占用更少的内存。
二、Lazy是什么
Lazy是一个类用于实现惰性加载Lazy Initialization。惰性加载是指对象的创建被推迟直到第一次被使用时LazyT允许在第一次访问对象时进行初始化这对于大型或资源密集型对象的性能优化非常有用。可以通过提供一个委托Delegate来延迟初始化对象。LazyT确保所有线程使用同一个惰性加载对象的实例并且丢弃使用的实例从而优化内存使用。
延迟初始化Lazy InitializationLazyT 允许你将对象的创建推迟到首次访问时。线程安全Thread-SafeLazyT 提供了线程安全的延迟初始化确保在多线程环境中也能正确工作。自动丢弃未使用的实例如果对象未被使用LazyT 会自动丢弃初始化失败的实例优化内存使用。支持复杂的初始化逻辑你可以提供一个委托允许你在初始化对象时执行复杂的逻辑。Value 属性通过 LazyT.Value 属性访问延迟初始化的对象。
三、Lazy基本用法
3.1 构造时使用默认的初始化方式
在使用Lazy时如果没有在构造函数中传入委托则在首次访问值属性时将会使用Activator.CreateInstance来创建类型的对象如果此类型没有无参数的构造函数时将会引发运行时异常。
本文实例类 public class Employee{public int Id { get; set; } 101;public string? Code { get; set; } G001;public string? Name { get; set; } 爷叔;public string? Address { get; set; } 上海市黄河路1001号;public Employee() {}public Employee(int id,string code,string name,string address) {this.Id id;this.Code code;this.Name name;this.Address address;}public void Show() {Console.WriteLine($Id{Id},Code{Code},Name{Name},Address{Address});}
}public static void Main(string[] arg)
{LazyEmployee lazyEmployee new LazyEmployee();Console.WriteLine($Main-is lazyData Initialized? value {lazyEmployee.IsValueCreated});lazyEmployee.Value.Show();//此处访问时才会将Data真正的初始化Console.WriteLine($Main-is lazyData Initialized? value {lazyEmployee.IsValueCreated});
}运行结果
Main-is lazyData Initialized? value False
Id101,CodeG001,Name爷叔,Address上海市黄河路1001号
Main-is lazyData Initialized? value True3.2 构造时使用指定的委托初始化 public static void Main(string[] arg){LazyEmployee lazyEmployee new LazyEmployee(() {Console.WriteLine(Main-lazyData will be Initialized!);return new Employee(2,G003,阿宝,上海市南京路001号);});Console.WriteLine($Main-is lazyData Initialized? value {lazyEmployee.IsValueCreated});lazyEmployee.Value.Show();//此处访问时才会将Data真正的初始化Console.WriteLine($Main-is lazyData Initialized? value {lazyEmployee.IsValueCreated});}运行结果
Main-is lazyData Initialized? value False
Main-lazyData will be Initialized!
Id2,CodeG003,Name阿宝,Address上海市南京路001号
Main-is lazyData Initialized? value True四、Lazy.Value使用
由上面两个应用可以看出Lazy对象创建后并不会立即创建对应地对象只有在变量的Value属性被首次访问时才会真正地创建同时会将其缓存到Value中,以便将来访问。
Value属性是只读的也就意味着如果Value存储了引用类型将无法为其分配新对象只可以更改此对象公共地属性或字段等如果Value存储的是值类型。那么就不能修改其值只能通过再次调用变量的函数使用新的参数来创建的变量。
在Lazy对象创建后在首次访问变量的Value属性前。
五、Lazy扩展用法
5.1 实现延迟属性
public class Customer
{private LazyEmployee employee;public int CustomerId { get; private set; }public Customer(int id, string code, string name, string address){this.CustomerId id;employee new LazyEmployee(() new Employee(this.CustomerId, C001, 李阿宝, 上海市南京西路1100号));}
}从上面介绍Lazy.Value中可以得知Value的属性是只读示例中只提供了Get的访问器并未提供Set的访问器。如果需要支持读取与写入属性的话则Set访问器必须创建一个新地Lazy对象同时必须编写自己的线程安全代码才能执行此操作。
5.2 Lazy实现惰性加载单例模式 public class SingletonT where T : class{private static readonly LazyT current new LazyT(() Activator.CreateInstanceT(), // factory methodtrue); // double lockspublic static object Current{get { return current.Value; }}}六、Lazy常用扩展方法 public Lazy (bool isThreadSafe) isThreadSafe 的布尔参数该方法参数用于指定是否从多线程访问 Value 属性。 如果想要仅从一个线程访问属性则传入 false 以获取适度的性能优势。 如果想要从多线程访问属性则传入 true 以指示 Lazy 实例正确处理争用条件初始化时一个线程引发异常。 public Lazy (LazyThreadSafetyMode mode) 提供线程安全模式 public Lazy (Func valueFactory) lambda 表达式传递给新的 Lazy 对象的构造函数。 下一次访问 Value 属性将导致新 Lazy 的初始化并且其 Value 属性此后会返回已分配给该属性的新值。