sndai
sndai

Reputation: 21

Static constructor does not seem to be called?

I have the following piece of code:

// using Windows.Storage;
internal static class AppData {
    private static ApplicationDataContainer container;
    public static bool FirstTime { get; } = !GetContainer("UserInfo").Values.ContainsKey("complete");
    static AppData() {
        container = ApplicationData.Current.LocalSettings;
    }
    private static ApplicationDataContainer GetContainer(string name) {
        return container.CreateContainer(name,ApplicationDataCreateDisposition.Always);
    }
}

NullReferenceException: Object reference not set to an instance of an object.

I don't know why it's wrong. Make some changes to the code

// using Windows.Storage;
internal static class AppData {
    private static ApplicationDataContainer container;
    public static bool FirstTime => !GetContainer("UserInfo").Values.ContainsKey("complete");
    static AppData() {
        container = ApplicationData.Current.LocalSettings;
    }
    private static ApplicationDataContainer GetContainer(string name) {
        return container.CreateContainer(name,ApplicationDataCreateDisposition.Always);
    }
}

OK, No error.

Why?

Upvotes: 2

Views: 149

Answers (2)

Martin Zikmund
Martin Zikmund

Reputation: 39072

There is a big difference in the two syntaxes:

public static bool Property { get; set; } = true;

This is a property initialization syntax and is evaluated before any constructor runs. The property can have a setter as well here.

public static bool Property => true;

This is an expression property, get-only and the right hand side is evaluated only when it is called. This also means that it is evaluated each time it is accessed, so it is not a good design choice to use a complex method call on the right-hand side for example.

Also if you want to have the expression syntax while ensuring the right-hand side will be evaluated only when actually needed and only once, you can combine this syntax with a private field:

private static bool? _property;

public static bool Property => _property ?? ( _property = CalculateProperty() );

This will first check if the private backing field is null and if yes, initialize it, while the assignment itself will then return the assigned value as well.

Upvotes: 4

Henk Holterman
Henk Holterman

Reputation: 273219

I'll have to look up the reference but the issue is that

public static bool FirstTime { get; } = ....;

is an initializer. And as an initializer it is executed just before the constructor.

When you change it to a function (or readonly lambda property), it is a normal member and it gets executed after the constructor.

Upvotes: 6

Related Questions