从函数返回数据的最佳实践是什么?是返回Null对象好还是返回空对象好?为什么要选择一种而不是另一种呢?
考虑一下:
public UserEntity GetUserById(Guid userId)
{
//Imagine some code here to access database.....
//Check if data was returned and return a null if none found
if (!DataExists)
return null;
//Should I be doing this here instead?
//return new UserEntity();
else
return existingUserEntity;
}
让我们假设在这个程序中存在有效的情况,即数据库中没有具有该GUID的用户信息。我认为在这种情况下抛出异常是不合适的??另外,我的印象是异常处理会损害性能。
把别人说的话用更简洁的方式来表达……
例外情况只适用于特殊情况
如果这个方法是纯数据访问层,我会说,给定一些参数,被包含在一个选择语句中,它将期望我可能找不到任何行,从中构建一个对象,因此返回null将是可接受的,因为这是数据访问逻辑。
另一方面,如果我希望我的参数反映一个主键,我应该只返回一行,如果我返回了不止一行,我就会抛出异常。0可以返回null, 2则不行。
现在,如果我有一些登录代码检查LDAP提供程序,然后检查DB以获得更多详细信息,并且我希望它们始终保持同步,那么我可能会抛出异常。正如其他人所说,这是商业规则。
Now I'll say that is a general rule. There are times where you may want to break that. However, my experience and experiments with C# (lots of that) and Java(a bit of that) has taught me that it is much more expensive performance wise to deal with exceptions than to handle predictable issues via conditional logic. I'm talking to the tune of 2 or 3 orders of magnitude more expensive in some cases. So, if it's possible your code could end up in a loop, then I would advise returning null and testing for it.
我们使用CSLA。NET,并且它认为失败的数据获取应该返回一个“空”对象。这实际上是相当烦人的,因为它要求检查obj。IsNew而不是obj == null。
正如前面提到的,null返回值将导致代码立即失败,从而降低了由空对象引起的隐形问题的可能性。
就我个人而言,我认为null更优雅。
这是一种非常常见的情况,我很惊讶这里的人似乎对此感到惊讶:在任何web应用程序中,数据通常是使用querystring参数获取的,这显然会被破坏,因此要求开发人员处理“未找到”的情况。
你可以这样处理:
if (User.Exists(id)) {
this.User = User.Fetch(id);
} else {
Response.Redirect("~/notfound.aspx");
}
...但是这每次都是对数据库的额外调用,这在高流量页面上可能是一个问题。而:
this.User = User.Fetch(id);
if (this.User == null) {
Response.Redirect("~/notfound.aspx");
}
...只需要一个呼叫。
对于集合类型,我将返回一个空集合,对于所有其他类型,我更喜欢使用NullObject模式来返回实现与返回类型相同接口的对象。有关该模式的详细信息,请查看链接文本
使用NullObject模式这将是:-
public UserEntity GetUserById(Guid userId)
{
//假设这里有一些代码来访问数据库.....
//Check if data was returned and return a null if none found
if (!DataExists)
return new NullUserEntity(); //Should I be doing this here instead? return new UserEntity();
else
return existingUserEntity;
}
class NullUserEntity: IUserEntity { public string getFirstName(){ return ""; } ...}
为了代码库的健康,我认为函数不应该返回null。我能想到几个原因:
将有大量的保护子句处理空引用if (f() != null)。
什么是空,它是一个公认的答案还是一个问题?null是特定对象的有效状态吗?(假设您是代码的客户端)。我的意思是所有引用类型都可以为空,但是它们应该为空吗?
当你的代码库不断增长时,使用null几乎总是会不时地产生一些意想不到的NullRef异常。
有一些解决方案,测试者-执行者模式或从函数式编程实现选项类型。