【问题标题】:Why test against null in this example?为什么在这个例子中针对 null 进行测试?
【发布时间】:2021-02-16 20:00:22
【问题描述】:

我按照本教程学习 MVVM 中的命令:

https://metanit.com/sharp/wpf/22.3.php

这是教程中命令的示例代码

private RelayCommand addCommand;
public RelayCommand AddCommand
{
    get
    {
        return addCommand ??
            (addCommand = new RelayCommand(obj =>
            {
                Phone phone = new Phone();
                Phones.Insert(0, phone);
                SelectedPhone = phone;
            }));
    }
}: 

据我了解,我们有一个私有支持字段addCommand 和公共属性AddCommand,它只有一个getter。在所述吸气剂中,字段 addCommand 针对null 进行测试。如果addCommand != null 则返回其值。否则将返回 RelayCommand 类的新示例。但是由于 AddCommand 没有设置器,包括私有的,这不意味着addCommand 字段将始终返回null 吗?为什么要针对总是返回null 的字段测试null?为什么要保留这样一个字段?

【问题讨论】:

    标签: c# mvvm


    【解决方案1】:

    您可能会遗漏 C# 中任何赋值返回所赋值的值的部分

    x = 1
    

    返回 1

    这意味着你可以做到

    y = x = 1
    

    而 y 也以 1 结束,因为 x=1 的结果是 1,这被分配给 y

    因此,您看到的模式为您的addCommand 提供了一次价值创造;如果addCommand 有一个值,则返回现有值,如果没有(即它是null),则?? 确保执行右侧执行赋值:addCommand 接收一个新值,然后作为“赋值的结果”返回(最终作为 get 的结果返回)。这个addCommand 然后会在下一次被调用时继续存在,这意味着它的创建只进行一次,并且在第一次需要时而不是默认情况下在创建封闭类时完成(我们称之为延迟加载/延迟实例化..)

    private int x = null;
    
    //if x is not null return x otherwise return: (assign 1 to x and return 1)
    get { return x ?? (x = 1); }  
    

    脚注:

    您可以考虑将代码重构为:

    get
    {
        if(addCommand == null){
            addCommand = new RelayCommand(obj =>
            {
                Phone phone = new Phone();
                Phones.Insert(0, phone);
                SelectedPhone = phone;
            }
        }
    
        return addCommand;
    }
    

    它并没有显着延长,而且性能相当,所以如果你能更好地理解它,那么它为你节省的时间将永远是利润:) - 有时 C# 开发人员可以去在寻求某种紧凑的单行方式来表达意图并最终得到同样“计算机可读”但不太“人类可读”的东西方面太过分了,如果你不能一眼就理解它可能会很好每次来看都浪费你的时间

    【讨论】:

    • 为什么不只是get {return new RelayCommand(...)}
    • @IgorCheglakov 将在每次调用该属性时创建一个新命令。这种方法是一种延迟加载技术。第一次调用该属性时,它将创建命令。后续调用将返回第一次调用中创建的值。
    • 确实;添加了一个脚注;考虑是否应该让这种模式保留在您的代码中。如果它让你感到困惑,它可能会让其他人感到困惑,花 20 秒时间来摇晃它可能意味着你在 6 个月内再次遇到它时不会发现自己感到困惑(或者下一个人会这样做)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多