[英]Should I check whether particular key is present in Dictionary before accessing it?
[英]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.