C# 方法应该处理空值吗?这种情况下的最佳实践?

C# 方法应该处理空值吗?这种情况下的最佳实践?,c#,parameters,null,C#,Parameters,Null,我在代码中有以下情况,管理它的最佳方法是什么,注释中包含了这些情况,请推荐最佳实践 try { string errorMessage = AccountClient.GetAccount(id, out accountDetails); // FIRST WAY : REMOVE THIS NULL CHECK AT ALL AND LEAVE GetAccountDetails to control // the Null situation? if (ac

我在代码中有以下情况,管理它的最佳方法是什么,注释中包含了这些情况,请推荐最佳实践

try
{
    string errorMessage = AccountClient.GetAccount(id, out accountDetails);

    // FIRST WAY : REMOVE THIS NULL CHECK AT ALL AND LEAVE GetAccountDetails to control
    // the Null situation?
    if (accountDetails == null)
    {
        // Second Way: This way? Throw exception here?
        throw new ArgumentNullException(nameof(accountDetails));
        //Third way? break the function?
        break;
    }

    // GetAccount Details already has null control
    Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
}
catch (Exception e)
{
    throw;
}

如果您可以对空输入做任何处理,那么请处理它

try
{
    string errorMessage = AccountClient.GetAccount(id, out accountDetails);

    if (accountDetails == null)
    {
         // do something about it. Maybe write some logs, substitute with a default value
         // or throw appropriate exception ...
    }

    Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
}
catch (Exception e)
{
    throw;
}
如果您不能,那么让
GetAccountDetails
决定应该发生什么

try
{
    string errorMessage = AccountClient.GetAccount(id, out accountDetails);
    Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
}
catch (Exception e)
{
    throw;
}

此外,也不需要捕获异常,不做任何操作,然后抛出它,这样您就可以删除整个try-catch块。

首先是构造

catch (Exception e) {
  throw; 
}
是多余的,可以消除。现在关于
null
s。有两个 案例:

  • null
    是一个错误的值,因此应该发出信号
  • null
    是预期的普通值,因此应继续执行
所以你有(
null
是一个错误)

或(
null
是预期结果)


这取决于这个ID来自哪里。如果用户输入了ID,那么我不会生成异常,因为它不是程序中的错误。只需处理用户输入并显示适当的消息。异常是昂贵的,所以我通常只在我有一个真正的程序失败时才使用它们。除此之外,如果您编写一个自定义异常处理程序,那么记录由错误用户输入引起的错误是没有意义的。所以我会这样做:

if (AccountClient.AccountExists(id))
{
    AccountDetails details = AccountClient.GetAccount(id);
    Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
}
无论如何,以同样的方式处理输入是很好的,即使您已经像上面那样处理了输入,以防有任何其他未处理的调用:

public AccountDetails GetAccount(int id)
{
    if (Exists(id))
        GetTheAccount(id);
    else
        throw new Exception(String.Format("Account {0} doesn't exists", id));
}

在这种情况下,我将使用异常,因为它实际上可能表示错误,例如,如果调用方函数传递了错误的值。

如果null不是预期值,则只抛出异常。如果你所有的假设都被打破了,那么继续下去就没有意义了。简单地中断方法而不抛出可能会在调用堆栈的其他地方导致错误,从而使调试问题原因变得更加困难。请注意,
break
不会“中断函数”,它打破了周围的循环。它看起来像是
AccountClient。如果失败,GetAccount
应该抛出异常,而不是返回错误消息。谢谢,留下try-catch块的优雅方式是什么?如果你可以对null做些什么,那么就处理它。如果不是,只需调用
GetAccountDetails
,让它决定应该发生什么。
if (AccountClient.AccountExists(id))
{
    AccountDetails details = AccountClient.GetAccount(id);
    Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
}
public AccountDetails GetAccount(int id)
{
    if (Exists(id))
        GetTheAccount(id);
    else
        throw new Exception(String.Format("Account {0} doesn't exists", id));
}