Lazy的选择之类内部字段与C#延迟加载

    延迟加载重要运用在偏下场景:

数据层 – ADO.NET或Entity Framework等ORM
反射 – 加载assemblies, types, MEF
缓存对象,领域实体

    上面以世界实体为例, 在实业中大家平常检查有个别属性下字段是或不是为空引用.
倘若是空的话,总结或填充这么些字段. 像那样:

   1:      /// <summary>

   2:      /// Order

   3:      /// </summary>

   4:      public class Order

   5:      { 

   6:          private Customer _customer;

   7:          /// <summary>

   8:          /// Gets the customer.

   9:          /// </summary>

  10:          public Customer Customer

  11:          {

  12:              get

  13:              {

  14:                  if (_customer == null)

  15:                  {

  16:                      _customer = new Customer();

  17:                  } return _customer;

  18:              }

  19:          }

  20:          /// <summary>

  21:          /// Prints the label.

  22:          /// </summary>

  23:          /// <returns></returns>

  24:          public string PrintLabel()

  25:          {

  26:              return Customer.CompanyName + "\n" + Customer.Address;

  27:          }

  28:      }

借使PrintLabel方法写成这么:

   1:          public string PrintLabel()

   2:          {

   3:              string result = _customer.CompanyName; // probably results in a NullReferenceException    

   4:              return result + "\n" + Customer.Address; // ok to access Customer  

   5:          }

留神上面第⑥行代码,也许有空引用相当.
上边大家使用Lazy<T>来缓解这么些难点:

   1:      /// <summary>

   2:      /// Order

   3:      /// </summary>

   4:      public class Order

   5:      {

   6:          /// <summary>

   7:          /// _customerInitializer

   8:          /// </summary>

   9:          private Lazy<Customer> _customerInitializer;

  10:   

  11:          /// <summary>

  12:          /// Initializes a new instance of the <see cref="Order"/> class.

  13:          /// </summary>

  14:          public Order()

  15:          {

  16:              _customerInitializer = new Lazy<Customer>(() => new Customer(),isThreadSafe:true);

  17:          }

  18:   

  19:          /// <summary>

  20:          /// Gets the customer.

  21:          /// </summary>

  22:          public Customer Customer

  23:          {

  24:              get{ return _customerInitializer.Value;}

  25:          }

  26:   

  27:          /// <summary>

  28:          /// Prints the label.

  29:          /// </summary>

  30:          /// <returns></returns>

  31:          public string PrintLabel()

  32:          {

  33:              string result = Customer.CompanyName; // ok to access Customer       

  34:              return result + "\n" + _customerInitializer.Value.Address; // ok to access via .Value  

  35:          }

  36:      }

地点的代码16行,大家延缓初阶化对像实例,并且安装线程安全. 
Lazy<T>内部是应用Func<T>来贯彻的,看下面其中构造器的源代码:

   1:  public Lazy(Func<T> valueFactory, LazyThreadSafetyMode mode)

   2:  {

   3:      if (valueFactory == null) throw new ArgumentNullException("valueFactory");

   4:      this.m_threadSafeObj = Lazy<T>.GetObjectFromMode(mode);

   5:      this.m_valueFactory = valueFactory;

   6:  }

有趣味请自行查看.net framework中的源码.
我们还足以扩展学一年级个LazyNotNull<T>

   1:      /// <summary>

   2:      /// LazyNotNull

   3:      /// </summary>

   4:      /// <typeparam name="T">Type</typeparam>

   5:      public class LazyNotNull<T>

   6:      {

   7:          private Lazy<T> _lazyValue = null;

   8:          private Func<T> _valueFactory = null;

   9:   

  10:          /// <summary>

  11:          /// Initializes a new instance of the <see cref="LazyNotNull&lt;T&gt;"/> class.

  12:          /// </summary>

  13:          /// <param name="valueFactory">The value factory.</param>

  14:          public LazyNotNull(Func<T> valueFactory)

  15:          {

  16:              _lazyValue = new Lazy<T>(valueFactory);

  17:              _valueFactory = valueFactory;

  18:          }

  19:   

  20:          /// <summary>

  21:          /// Gets T value.

  22:          /// </summary>

  23:          public T Value

  24:          {

  25:              get

  26:              {

  27:                  var lazyValue = _lazyValue;

  28:                  if (lazyValue.Value != null)

  29:                  {

  30:                      return lazyValue.Value;

  31:                  }

  32:                  _lazyValue = new Lazy<T>(_valueFactory);

  33:                  return default(T);

  34:              }

  35:          }

  36:      }

梦想那篇POST对你支付有帮忙.
你大概感兴趣的稿子:

.net4.0下的Lazy<T>类型大致利用
.net3.5下选拔LINQ递归算法达成简洁代码

作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
正文版权归小编和天涯论坛共有,欢迎转发,但未经小编同意必须保留此段评释,且在篇章页面明显地方给出原来的作品连接,不然保留追究法律权利的权利。
该作品也还要宣布在自家的单独博客中-Petter Liu
Blog

相关文章