c# - 手动设置 Lazy<T> 的值

标签 c# .net .net-4.0

我有一个对象,它是根据网络服务的响应创建的。如果我得到这些对象的列表,它们只有最少的信息(在下面的示例中,列表响应中返回 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,则调用网络服务以下载更详细的数据集并填充 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 实现中,该函数将在访问惰性对象时被调用,但实际上不会返回数据。它会执行一些计算并立即初始化所有惰性值。

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

最佳答案

听起来你想要一个单例 Lazy<T>它构造了一个具有 两个 值的复合对象。A 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类型 - 如果您最终拥有多个属性,我建议您这样做。实际上,您希望延迟获取详细响应,然后提供对其中各个属性的简化访问。

关于c# - 手动设置 Lazy<T> 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3463340/

相关文章:

c# - Gmail 中未读邮件的数量

.net - 在 Dev Machine 上备份 Visual Studio 解决方案的最佳实践

c# - 返回带有 Ajax 的 PartialView 未在页面上插入

c# - 使用字符串、int 数组反序列化 json - .net core C#

c# - 检查长度和非字母数字字符的 .NET 正则表达式

c# - 已经有一个打开的 DataReader 与此命令关联,必须先在 C# 中将其关闭

c# - 从 mht 中提取文本

c# - 使用 LINQ 连接 List<List<string>> 中的所有字符串

c# - 使用 .NET 4 让程序最小化到系统托盘的最简单方法

c# - 自使用 .Net 4.0 以来 visual studio Release模式中的 InvalidOperationException