强制创建惰性对象

本文关键字:对象 创建 | 更新日期: 2023-09-27 18:33:49

我得到了一个Lazy项目的集合。然后我想一次性强行"创建"它们。

void Test(IEnumerable<Lazy<MailMessage>> items){
}

通常,对于Lazy项,在访问其成员之一之前,不会创建包含的对象。

鉴于没有ForceCreate()方法(或类似方法),我被迫执行以下操作:

var createdItems = items.Where(a => a.Value != null && a.Value.ToString() != null).Select(a => a.Value);

这是使用ToString()强制创建每个项目。

有没有更整洁的方法来强制创建所有项目?

强制创建惰性对象

获取所有延迟初始化值的列表:

var created = items.Select(c => c.Value).ToList();
创建

所有惰性项需要两件事,需要枚举所有项(但不一定保留它们),并且需要使用 Value 属性来创建项。

items.All(x => x.Value != null);

All 方法需要查看所有值以确定结果,以便枚举所有项(无论集合的实际类型如何),并且对每个项使用 Value 属性将导致它创建其对象。(!= null部分只是创建一个All方法可以接受的值。

看到没有 ForceCreate() 方法(或类似方法)

您始终可以在Lazy<T>上为此创建ForceCreate()扩展方法:

public static class LazyExtensions
{
    public static Lazy<T> ForceCreate<T>(this Lazy<T> lazy)
    {
        if (lazy == null) throw new ArgumentNullException(nameof(lazy));
        _ = lazy.Value;
        return lazy;
    }
}

。在IEnumerable<T>上附有ForEach扩展方法:

public static class EnumerableExtensions
{
    public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
    {
        if (enumerable == null) throw new ArgumentNullException(nameof(enumerable));
        if (action == null) throw new ArgumentNullException(nameof(action));            
        foreach (var item in enumerable)
        {
            action(item);
        }
    }
}

通过组合这两种扩展方法,您可以一次性强制创建它们:

items.ForEach(x => x.ForceCreate());