【问题标题】:Static constructor does not seem to be called?静态构造函数似乎没有被调用?
【发布时间】:2018-03-19 12:03:44
【问题描述】:

我有如下一段代码:

// 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:对象引用未设置为对象的实例。

我不知道为什么会出错。对代码进行一些更改

// 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);
    }
}

好的,没有错误。

为什么?

【问题讨论】:

  • 您是否检查了 ApplicationData 是否为 null 或 ApplicationData.Current 是否为 null ?
  • 这不是一个真正的空参考问题。在第一个代码块中你有一个属性初始化器,在第二个你有一个函数定义。
  • 第一个版本设置了一个只读属性(带有支持字段)并在静态构建时分配给支持字段。第二个设置了一个属性(只有一个 getter)没有支持字段。第二个将起作用,因为当您调用它时,container 将不再是 null

标签: c# .net uwp


【解决方案1】:

我必须查一下the reference,但问题是

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

是一个初始化器。作为初始化器,它在构造函数之前执行。

当您将其更改为函数(或只读 lambda 属性)时,它是一个普通成员,并且在构造函数之后执行。

【讨论】:

  • 这是节省查找时间的参考:stackoverflow.com/a/8285210/5311735
  • 我第二个@mjwills。 "=>" 将创建一个没有支持字段的只读 Prop,不是吗?
  • @Fildor 它确实是一个只读属性。但是只读属性基本上是一个函数(比如GetFirstTime),所以这个问题的区别并不重要。它仍然是属性,例如由Type.GetProperty("FirstTime") 返回。
  • 但是您对属性的看法是正确的,它是bool FirstIme => ...,并且方法看起来像bool FirstIme() => ...。语义是一样的。
【解决方案2】:

两种语法有很大区别:

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

这是一种属性初始化语法,在任何构造函数运行之前进行评估。该属性在这里也可以有一个设置器。

public static bool Property => true;

这是一个表达式属性,只能获取,只有在调用它时才计算右侧。这也意味着每次访问时都会对其进行评估,因此例如在右侧使用复杂的方法调用不是一个好的设计选择。

此外,如果您希望拥有表达式语法,同时确保仅在实际需要时才评估右侧并且仅评估一次,您可以将此语法与私有字段结合使用:

private static bool? _property;

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

这将首先检查私有支持字段是否为null,如果是,则对其进行初始化,而赋值本身也会返回分配的值。

【讨论】:

    猜你喜欢
    • 2011-11-16
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 2012-09-05
    • 1970-01-01
    • 2021-07-13
    • 2016-07-12
    • 1970-01-01
    相关资源
    最近更新 更多