从函数返回数据的最佳实践是什么?是返回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,因为这是我所期望的DAL/Repository层的操作方式。

如果它不存在,不要返回任何可以被解释为成功获取对象的东西,null在这里工作得很好。

最重要的是在你的DAL/Repos层保持一致,这样你就不会对如何使用它感到困惑。

其他回答

这取决于什么对你的案子最有意义。

返回null是否有意义?“不存在这样的用户”?

或者创建一个默认用户有意义吗?当您可以安全地假设如果用户不存在,则调用代码在请求时希望用户存在时,这是最有意义的。

或者,如果调用代码要求使用无效ID的用户,抛出异常(如“FileNotFound”)是否有意义?

然而,从分离关注点/SRP的角度来看,前两点更为正确。从技术上讲,第一个是最正确的(但只差一点点)——GetUserById应该只负责一件事——获取用户。通过返回其他内容来处理自己的“用户不存在”情况可能违反SRP。如果您确实选择抛出异常,则分隔为不同的check - bool DoesUserExist(id)是合适的。

根据下面大量的评论:如果这是一个api级别的设计问题,这个方法可以类似于“OpenFile”或“readwholfile”。我们正在从某个存储库中“打开”一个用户,并从结果数据中补充对象。在这种情况下,一个例外可能是合适的。也许不是,但也有可能。

所有的方法都是可以接受的——这取决于API/应用程序的上下文。

我个人会返回null,因为这是我所期望的DAL/Repository层的操作方式。

如果它不存在,不要返回任何可以被解释为成功获取对象的东西,null在这里工作得很好。

最重要的是在你的DAL/Repos层保持一致,这样你就不会对如何使用它感到困惑。

就我个人而言,我使用NULL。它清楚地表明没有数据要返回。但在某些情况下,空对象可能是有用的。

如果用户没有被找到的情况经常出现,你想要根据情况以各种方式处理(有时抛出异常,有时替换一个空用户),你也可以使用接近f#的Option或Haskell的Maybe类型,它显式地将“无值”情况与“发现了一些东西!”数据库访问代码看起来像这样:

public Option<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 Option<UserEntity>.Nothing; 
 else
    return Option.Just(existingUserEntity);
}

并且像这样使用:

Option<UserEntity> result = GetUserById(...);
if (result.IsNothing()) {
    // deal with it
} else {
    UserEntity value = result.GetValue();
}

不幸的是,每个人似乎都有自己喜欢的类型。

我是一名法国IT专业的学生,所以请原谅我的英语不好。在我们的类中,我们被告知这样的方法永远不应该返回null,也不应该返回空对象。这种方法的用户应该在尝试获取对象之前首先检查他正在寻找的对象是否存在。

使用Java,我们被要求添加一个断言exists(object):“您不应该尝试访问一个不存在的对象”;在任何可能返回null的方法的开头,以表达“先决条件”(我不知道英文单词是什么)。

在我看来,这真的不容易使用,但这就是我正在使用的,等待更好的东西。