.NET Framework 4.0 中的 Lazy(Of T) 类






4.67/5 (6投票s)
在 .NET Framework 4.0 中以延迟方式初始化对象
引言
.NET Framework 提供了一个名为 Lazy<T>
的新类,用于以延迟方式初始化对象。它包括初始化值类型以及使用 null
值的功能。使用这个类,我们可以非常有效地实现复杂的导航相关应用程序,并减少内存使用。例如,考虑一下这种情况:我有一个属性,它在 Silverlight 应用程序中保存了大约 50 个用户控件的数组。在这种情况下,我需要在主页上显示五个用户控件,但需要在应用程序加载时初始化所有这五十个用户控件以获取实际引用,因为我需要在用户控件之间进行一些元素绑定。同时,其余用户控件将在用户显式导航时显示。
必备组件
- .NET Framework 4.0
- Windows XP, 2003, Vista, Windows7, VS2010
典型的 .NET 对象初始化
如果我们使用典型的 .NET 属性声明/初始化方式,而不使用 Lazy
类来实现这样的应用程序,那么所有用户控件都将在我们使用 new
关键字将项目添加到我的数组属性时初始化。以下是典型的 .NET 初始化方式。
//Property declaration
private UserControl[] loadMyUserControl;
public UserControl[] LoadMyUserControl
{
get
{
return loadMyUserControl;
}
set
{
loadMyUserControl = value;
}
}
//Initializing property.
public MainPage()
{
InitializeComponent();
var userControls = new UserControl[]
{
new UserControl1(),
new UserControl2(),
new UserControl3()
};
}
在这种方法中,当用户打开我的应用程序并关闭而不导航到其他页面时,我的应用程序会消耗不必要的内存(大约 45 个用户控件的内存)。
延迟初始化
但是,延迟初始化发生在第一次访问 Lazy<T>.Value
属性或调用 Lazy<T>.ToString
方法时。对于我的场景,只有在加载我的应用程序时才会创建五个用户控件的实例和内存。其余用户控件将在用户通过主页上的导航链接导航到相应页面时创建。以下是延迟加载的代码片段。
//Property declaration
private Lazy[] loadMyUserControl;
public Lazy[] LoadMyUserControl
{
get
{
return loadMyUserControl;
}
set
{
loadMyUserControl = value;
}
}
//Initializing property.
public MainPage()
{
InitializeComponent();
LoadMyUserControl = new Lazy[]
{
new Lazy(() => {return new UserControl1();
}),
new Lazy(() => {return new UserControl2();
}),
new Lazy(() => {return new UserControl3();
})
};
}
现在我将根据运行时导航加载我的用户控件,如下所示
//Loading my fifth user control on button click
private void Button_Click_1(object sender, RoutedEventArgs e)
{
if (!TopPanel.Children.Contains(LoadMyUserControl[5].Value))
TopPanel.Children.Add(LoadMyUserControl[5].Value);
}
注意:TopPanel
是应用程序主页上的堆栈面板。请参阅演示示例以获取更多信息。
运行演示应用程序并单击“Status”按钮。检查用户控件的状态。如以下快照所示,仍然没有加载所有用户控件。

单击“Load UserControl1”按钮并检查状态。现在您可以看到,第一个用户控件已加载到视图中,状态已更改为 True
。框架 4.0 中一个很棒的功能!:)

您可以参考 MSDN 文档,以获取有关 Lazy
类的更多信息。
关注点
实际上,当我开始阅读关于 MEF 的内容时,我注意到了这个功能。 似乎 MEF 主要使用此功能来导入/导出契约。 但我不确定。 因为我不是 MEF 的作者。:)
历史
- 2010 年 8 月 26 日:初始帖子