3

I'm having trouble initializing properties within a class using the method described in this documentation.

Sample:

public class MyClass
{
    private Lazy<string> _lazyString;

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

    public string MyString => _lazyString.Value;
}

When I debug I can see that _lazyString has its boolean IsCreated set to true before I've even accessed the MyString property. Has something changed in the recent c# iterations?

My target framework is netcoreapp3.1

5
  • 3
    How do you debug your code? By looking with a debugger on a property you will trigger the lazy operation. Commented Sep 24, 2021 at 21:49
  • @Progman Dangit you beat me to it by just a couple seconds! The real test here is to either use a class that has some measurable activity when it's instantiated, like outputting something to the console, or to check the IsCreated property in code without looking at the property it's being used in. Commented Sep 24, 2021 at 21:51
  • The thing is: when I do not provide a property to access the value of the lazy field, the field remains uninitialized! So it feels as though the compiler is optimizing the property Commented Sep 24, 2021 at 21:54
  • I am using VS19. Nothing fancy Commented Sep 24, 2021 at 21:54
  • 1
    You can use Lazy.IsValueCreated (see learn.microsoft.com/en-us/dotnet/api/…) to check if the value for the Lazy object has been created. Commented Sep 24, 2021 at 21:57

1 Answer 1

7

Works as expected.

The problem with testing this with the debugger, as pointed out by @Progman, is that by hovering the value you trigger the lazy operation.

To really test the laziness in this case you can use the Lazy.IsValueCreated property.

You can see with the following code

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;

}

Output:

MyString not yet called. 
Is value created? False 
MyString called. 
Is value created? True
Sign up to request clarification or add additional context in comments.

2 Comments

Tried in my own VS. So it really is the debugger "fake" initializing the value.
Pausing execution on the second console printout shows IsValueCreated with a value of false but c._lazyString.IsValueCreated with a value of true

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.