类方法:我是否应该在访问变量之前始终检查变量

本文关键字:变量 检查 访问 是否 类方法 | 更新日期: 2023-09-27 17:55:57

对不起,这个愚蠢的问题。

假设我有这个类(代码是 C# 的):

class Foo {
    public List<string> Bars { get; set; }        
    public Foo() { }
}

现在我想实现一个在柱上执行一些操作的方法,例如 Foo.Translate()。

我是否

应该始终检查我尝试访问/修改的内容是否为空或无效?

class Foo {
    public List<string> Bars { get; set; }        
    public Foo() { }
    public void Translate()
    {
        // Should I check with a null && count > 0?
        if (Bars != null && Bars.Count > 0)
        {
            [...]
        }
    }
}

类方法:我是否应该在访问变量之前始终检查变量

这取决于。

如果值为 null 并且不应该是,则显然出了问题,无论您正在做什么,现在都是无效的场景,无论如何都会给您错误的结果。让它抛出异常。检查日志以找出它为 null 的原因,并修复该错误。

如果值为 null 是有效的方案,则适合执行您正在执行的操作。

最好在构造函数中验证属性,如果它们无效,则引发异常。这样,您可以保证每次访问此属性时都应该没问题。而且,使用私有 setter 设置属性也很好,这样只有构造函数或自定义方法才能更新您的类属性。

class Foo {
    public List<string> Bars { get; private set; }        
    public Foo(List<string> bars) 
    { 
        if (bars!= null && bars.Count > 0)
        {
         this.Bars = bars
        }
    }
}

你永远不应该公开集合的setters(它把你的内部暴露给外部,它违反了封装)。您应该在构造函数中初始化集合。这样你就知道它永远不会为空。

对此有一个代码分析警告 - https://msdn.microsoft.com/en-us/library/ms182327.aspx

这完全取决于您的期望。如果您希望 Foo 需要 Bars 集合,请让用户在构造函数中传递它并在那里对其进行验证(并使其成为私有的)。

如果您希望在 Foo 类中填充 Bar,则应确保列表始终在构造函数中实例化(并使其成为私有的)。这将避免空检查。

如果您希望它在执行某些操作之前具有计数> 0,则在执行该操作之前,您应该验证该计数> 0。

由于代码中存在构造函数,因此可以在构造函数中检查值的空值。通常,如果该值预期不为 null,则可以使用:

class Foo {
    public List<string> Bars { get; set; }        
    public Foo(string bars) { 
        try
        {
           if(bars == null){ bars = "" } //Whatever value bars should be if null, in this case an empty string.
        {
        catch(Exception)
        {
           throw;
        }
    }
    public void Translate()
    {
        // Should I check with a null && count > 0?
        if (Bars != null && Bars.Count > 0)
        {
            [...]
        }
    }
}

我相信这更快,因为当对象 Foo 实例化时,会检查任何空值。

如果在正常情况下不应该null某些东西,那么不要检查。让应用程序引发异常。否则,如果您确实检查并且null,您将该怎么办?您可以用其他内容替换null,但该值正确吗?

但更好的方法是用铁腕控制你的班级的状态。如果List<string> Bars不应为 null,则不要让它为 null。不允许对象将自身置于无效状态,也不允许其他对象将其置于无效状态。如果无法null那么您不必到处检查。 null检查无处不在是一种瘟疫,表明我们不知道代码的状态是什么。

最简单的形式是:

class Foo {
    public List<string> Bars { get; } = new List<string>();     
    public Foo() { }
}

你也可以做

class Foo {
    private readonly List<string> _bars = new List<string>();
    public List<string> Bars { get { return _bars; } }
    public Foo() { }
}

现在,_bars在创建Foo时设置为新列表,编译器将阻止您更改_bars。您只能修改其内容。现在,只要您使用此类,您就不必担心_bars(或扩展Bars)是否null

返回集合或其他对象的方法也是如此。如果没有什么可退货的,请不要归还null.返回接收方法可以无害地处理的空数组或"空"对象。