在 C# 中变得懒惰

2025-06-09

在 C# 中变得懒惰

如果您和我一样,也一直在寻找提升应用程序运行速度的方法。在本文中,我将向您展示 .NET 框架中一个鲜为人知的类,它能够轻松实现对象的惰性创建,并且保证线程安全。

旧方法

在我们讨论有趣的东西之前,让我们先看看如何在没有.NET 的Lazy<T>类的情况下尝试做这些事情。

通常,当你设计一个类时,你可能会从这样的代码开始:

您最终可能会发现,随着需要实例化的事物数量的增加,创建对象时的性能会显著下降。

在这种情况下,您可能会决定延迟加载该类的组件Starship。也就是说,您可能决定仅在需要时才实例化它们。

典型版本如下:

那里有很多行。值得庆幸的是,这可以稍微压缩一下:

好吧,尽管可能不是特别容易阅读,但至少它是简洁的。

然而,扩展版本和简洁版本都存在线程问题。

如果两个调用者尝试获取同一个属性,则有可能其中一个调用者通过了空值检查,然后其线程进入休眠状态,而另一个线程也通过了该空值检查。在这种情况下,ExpensiveWarpCore会创建两个 的实例,然后将其赋值给_warpCore。这可能不成问题,也可能造成严重后果。

为了完全解决这个限制,您需要执行以下操作:

虽然从技术上讲这更安全,但您可以开始看到,当您引入新的延迟加载属性时,在您的类中多次执行此操作会变得乏味,并使人们倾向于浏览代码。

略读是不好的,并且会让错误隐藏起来,所以让我们寻找更好的方法。

引入 Lazy<T>

.NET 提供了一个名为的通用类Lazy,它允许您在第一次请求对象的值时延迟实例化对象。

让我们使用以下方法看一下相同的代码Lazy<T>

有趣的是,我们将复杂性从属性获取器中移出并将其放在支持字段中。

让我们看一下这个惰性初始化程序:

new Lazy<WarpCore>(() => new ExpensiveWarpCore(), true)

首先,我们调用构造函数Lazy并提供一个泛型类型参数,告诉类它将提供一个WarpCore实例。

接下来,我们传入一个Func<WarpCore>参数,该参数将被调用来创建所需的实例。在本例中,我们只是调用了ExpensiveWarpCore构造函数。请注意,如果我们只是调用默认构造函数WarpCore而不是ExpensiveWarpCore,则甚至不需要指定这个Func值。

最后,我们将一个true布尔值传递给最后一个参数,表明该实例应该是线程安全的。

结束语

您只需几行代码就能看到如何Lazy<T>在第一次使用对象时安全、简洁地实例化对象,并且如果愿意的话,还可以以线程安全的方式执行此操作。

和任何事情一样,使用 Lazy 也有一些弊端。首先,这些弊端涉及到语法,对于新开发者来说,这些语法可能难以阅读。

总而言之,Lazy我强烈建议将其添加到您的标准实践中。它的缺点很小,而且能够将简单的模式标准化,这是一个巨大的优势。

文章“在 C# 中变得懒惰”首先出现在Kill All Defects上。

鏂囩珷鏉ユ簮锛�https://dev.to/integerman/getting-lazy-in-c-4dk5
PREV
神之物件:如何召唤Codethulhu
NEXT
游戏设计与事件建模