提早初始化
是一种将对象的创立提早到第一次须要用时的技术,换句话说,对象的初始化是产生在真正须要的时候才执行,值得注意的是,术语 提早初始化
和 提早实例化
的意思是雷同的——能够调换应用,通过应用 提早初始化
技术,能够防止应用程序不必要的计算和内存耗费,这篇文章咱们将会探讨如何在 C# 中应用 提早初始化。
有些敌人听完这些可能会懵逼,接下来用一个简略的例子来理解下 提早加载
的场景,思考上面两个类, Customer
和 Order
, Customer 类蕴含了一个 Orders 属性,一个人必定会有很多的订单,也就意味着它可能蕴含了很多的数据,甚至还须要连贯数据库去获取 Orders 记录,在这种场景下,没必要给 customer 汇合中的所有人都带上残缺的 orders,这个初始化开销是微小的,优化点就是不加载 Orders,直到某些 customer 真的须要 Orders 时才按需灌入。
应用 Lazy<T>
你能够本人写一段逻辑来实现 提早初始化
,在 .Net Framework 4.0
之后就没必要了, 因为在 System
命名空间下曾经提供了 Lazy<T>
,而且还是 线程平安
的,能够应用这个类来提早 资源密集型 的对象按需创立。
当应用 Lazy<T>
的时候,这里的 T 就是你要提早的汇合,那如何做到按需加载呢?调用 Lazy<T>.Value
即可,上面的代码片段展现了如何应用 Lazy<T>
。
Lazy<IEnumerable<Order>> orders = new Lazy<IEnumerable<Order>>();IEnumerable<Order> result = lazyOrders.Value;
当初,思考上面的两个类: Author
和 Blog
,一个作者能够写很多文章,所以这两个类之间是 一对多
的关系,上面的代码片段展现了这种关系。
public class Author { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Address { get; set; } public List<Blog> Blogs { get; set; } } public class Blog { public int Id { get; set; } public string Title { get; set; } public DateTime PublicationDate { get; set; } }
值得注意的是,关系型数据库中的 一对多
关系映射到对象模型就是 Author
类中减少一个 List Blogs 属性,应用这个属性,Author 就能够维持一个或者多个 Blog 实例对象,对吧。
当初假设在 用户界面
上仅需展现 Author 的根底信息,比如说:(firstname,lastname,address),在这种场景下,给 Author 对象加载 Blogs 汇合是毫无意义的,当真的须要加载 Blogs 时,执行 Blogs.Value 即可立刻执行,上面展现了 Lazy<Blog> Blogs
的用法。
public class Author { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Address { get; set; } public Lazy<IList<Blog>> Blogs => new Lazy<IList<Blog>>(() => GetBlogDetailsForAuthor(this.Id)); private IList<Blog> GetBlogDetailsForAuthor(int Id) { //Write code here to retrieve all blog details for an author. } }
应用通用的 Lazy
接下来让咱们看看如何应用泛型的 Lazy
实现单例模式,上面的 StateManager
是线程平安的,同时为了演示 提早初始化
,我应用了 动态构造函数 来确保 C# 编译器不会将它标记为 beforefieldinit
。
public sealed class StateManager { private StateManager() { } public static StateManager Instance { get { return Nested.obj; } } private class Nested { static Nested() { } internal static readonly StateManager obj = new StateManager(); } }
上面我用 Lazy<T>
来包装 StateManager,你会发现应用 Lazy<T>
来做提早初始化真的是太简略了。。。
public class StateManager { private static readonly Lazy<StateManager> obj = new Lazy<StateManager>(() => new StateManager()); private StateManager() { } public static StateManager Instance { get { return obj.Value; } } }
能够瞄一下下面代码的 Instance 属性,它被做成只读属性了,同时也要留神 obj.Value
也是一个只读属性。
public class Lazy<T> { public T Value { get { if (_state != null) { return CreateValue(); } return _value; } } }
提早初始化 是一个很不错的性能优化技术,它容许你将那些 资源密集型 的对象提早到你真正须要加载的时候再加载,大家联合本人的场景纵情的应用吧!
译文链接:https://www.infoworld.com/art...
更多高质量干货:参见我的 GitHub: csharptranslate