延迟属性初始化在 C 中不起作用#

Lazy property initialization not working in C#

提问人:st0ve 提问时间:9/25/2021 最后编辑:deczalothst0ve 更新时间:2/24/2022 访问量:1647

问:

我在使用本文档中描述的方法初始化属性时遇到问题。class

样本:

public class MyClass
{
    private Lazy<string> _lazyString;

    public MyClass()
    {
        _lazyString = new Lazy<string>(() => "hello world");
    }

    public string MyString => _lazyString.Value;
}

当我调试时,我可以看到在我访问该属性之前,它的布尔值已设置为。在最近的 c# 迭代中是否发生了一些变化?_lazyStringIsCreatedtrueMyString

我的目标框架是netcoreapp3.1

C# .net-core 延迟初始化

评论

3赞 Progman 9/25/2021
如何调试代码?通过使用调试器查看属性,将触发惰性操作。
0赞 Logarr 9/25/2021
@Progman Dangit,你只用了几秒钟就打败了我!这里真正的测试是使用在实例化时具有一些可测量活动的类,例如将某些内容输出到控制台,或者在代码中检查属性而不查看正在使用它的属性。IsCreated
0赞 st0ve 9/25/2021
问题是:当我不提供属性来访问惰性字段的值时,该字段仍未初始化!所以感觉好像编译器正在优化属性
0赞 st0ve 9/25/2021
我正在使用 VS19。没什么花哨的
1赞 Progman 9/25/2021
您可以使用 (请参阅 learn.microsoft.com/en-us/dotnet/api/...) 来检查是否已创建对象的值。Lazy.IsValueCreatedLazy

答:

6赞 deczaloth 9/25/2021 #1

按预期工作。

正如 @Progman 所指出的,使用调试器进行测试的问题在于,通过悬停该值,您可以触发延迟操作。

在这种情况下,若要真正测试延迟性,可以使用 Lazy.IsValueCreated 属性。

你可以用下面的代码看到

static void Main(string[] args)
{

    MyClass c = new MyClass();
    Console.WriteLine($"MyString not yet called.");
    Console.WriteLine($"Is value created? {c.IsValueCreated}");
    var s = c.MyString;
    Console.WriteLine($"MyString called.");
    Console.WriteLine($"Is value created? {c.IsValueCreated}");
}

public class MyClass
{
    private Lazy<string> _lazyString;

    public MyClass()
    {
        _lazyString = new Lazy<string>(() => "hello world");
    }

    public string MyString => _lazyString.Value;

    public bool IsValueCreated => _lazyString.IsValueCreated;

}

输出:

MyString not yet called. 
Is value created? False 
MyString called. 
Is value created? True

评论

1赞 st0ve 9/25/2021
在我自己的 VS 中尝试过。因此,它实际上是调试器“假”初始化值。
0赞 st0ve 9/25/2021
在第二个控制台打印输出上暂停执行时,显示值为 false,但值为 trueIsValueCreatedc._lazyString.IsValueCreated