2010-08-11 41 views
3

我有一个对象,我从web服务的响应中创建。如果我得到这些对象的列表,它们的信息量最小(在下面的示例中,ID,Prop1和Prop2在列表响应中返回)。如果我通过ID获取对象,则会返回完整的一组信息,包括Prop3和Prop4中的子对象。手动设置懒惰值<T>

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,那么我只能通过访问它来单独填充每个属性。这会导致相同的webservice调用,每次只解析一小部分响应。我希望能够做的就是创建每个懒惰像这样:

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,如果我可以避开它的话。

回答

2

这听起来像你想Lazy<T>它构造与在一个Tuple<Bar, Bar2>意愿工作都值的复合对象:

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() 
{ 
    ... 
} 

当然,代替Tuple你可以有一个DetailedResponse类型 - 我建议,如果你最终有超过几个属性。实际上,您希望懒惰地获取详细的响应,然后提供对其中各个属性的简化访问。

1

懒惰只得到你要的是什么,所以问他们在一起......

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; } 
}