繁体   English   中英

类方法:在访问变量之前,我应该始终检查变量吗?

[英]Class methods: should I always check variables before accessing them?

很抱歉这个愚蠢的问题。

假设我有此类(代码在C#中):

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

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

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

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是有效的方案,则应该执行您正在做的事情。

优良作法是在构造函数中验证属性,如果属性无效则抛出Exception。 这样,您可以保证每次访问此属性都可以。 同样,用私有设置器设置属性也很好,这样只有构造函数或自定义方法可以更新您的类属性。

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

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

为此有一个代码分析警告-https://msdn.microsoft.com/zh-cn/library/ms182327.aspx

这都是关于您的期望。 如果您期望Foo需要Bars集合,请让用户在构造函数中传递它,并在其中进行验证(并将其私有)。

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

如果您希望它在执行某些操作之前计数> 0,则应像执行操作一样,先验证count> 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检查到处都是困扰,这是一个我们不知道代码状态是什么的信号。

最简单的形式:

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() { }
}

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

返回集合或其他对象的方法也是如此。 如果没有返回null ,请不要返回null 返回一个空数组或一个“空”对象,接收方法可以无害地使用该对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM