【问题标题】:Manually setting the Value of Lazy<T>手动设置 Lazy<T> 的值
【发布时间】:2011-03-28 15:50:42
【问题描述】:

我有一个从网络服务的响应中创建的对象。如果我得到这些对象的列表,它们的信息量很少(在下面的示例中,ID、Prop1 和 Prop2 在列表响应中返回)。如果我通过ID获取对象,则返回全套信息,包括Prop3和Prop4中的子对象。

public class Foo
{
    public Guid ID { get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }

    public Lazy<IEnumerable<Bar>> Prop3 { get; }
    public Lazy<IEnumerable<Bar2>> Prop4 { get; }
}

我希望能够做的是在部分构造时使用这个对象,但是如果访问 Prop3 或 Prop4,则调用 web 服务以下载更详细的数据集并填充 Prop3 和 Prop4。

如果我使用 Lazy,那么我只能通过访问它来单独填充每个属性。这将导致相同的 Web 服务调用,每次只解析一小部分响应。我想要做的是像这样创建每个 Lazy:

Prop3 = new Lazy<IEnumerable<Foo>>(() => LoadDetailedInformation());

private void LoadDetailedInformation()
{
    // Get info from web service
    Prop3.Value = ParseProp3(response);
    Prop4.Value = ParseProp4(response);
}

所以在这个假装的延迟实现中,当访问延迟对象时会调用该函数,但实际上不会返回数据。它会执行一些计算并立即初始化所有惰性值。

我最好还是滚动自己的 Lazy,还是有另一种方法可以做到这一点,而无需为每个属性编写大量包装代码?我正在为其执行此操作的其中一个类有大约 20 个需要像这样包装的对象,所以如果我能侥幸逃脱的话,我不想编写实际的 getter 和 setter。

【问题讨论】:

    标签: c# .net .net-4.0


    【解决方案1】:

    听起来你想要一个 single Lazy&lt;T&gt; 构造一个包含 both 值的复合对象。Tuple&lt;Bar, Bar2&gt; 将完成这项工作:

    public Bar Prop3 { get { return lazy.Value.Item1; } }
    public Bar2 Prop4 { get { return lazy.Value.Item2; } }
    
    private readonly Lazy<Tuple<Bar, Bar2>> lazy =
        new Lazy<Tuple<Bar, Bar2>>(LoadDetailedInformation);
    
    private Tuple<Bar, Bar2> LoadDetailedInformation()
    {
        ...
    }
    

    当然,您可以使用DetailedResponse 类型而不是Tuple - 如果您最终拥有多个属性,我建议您这样做。实际上,您希望懒惰地获得详细的响应,然后提供对其中各个属性的简化访问。

    【讨论】:

      【解决方案2】:

      Lazy 只会得到你想要的东西,所以一起请求它们......

      public class Foo
      {
          public Guid ID { get; set; }
          public string Prop1 { get; set; }
          public string Prop2 { get; set; }
          public Lazy<SubFoo> SubFoo{ get; }
      }
      
      public class SubFoo
      {
          public IEnumerable<Bar> Prop3 { get; }
          public IEnumerable<Bar2> Prop4 { get; }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多