方法应该处理空值?在这种情况下的最佳做法?
问题描述:
我在代码中遇到以下情况,最佳管理方式是什么,评论中包含情况,并请推荐最佳实践。方法应该处理空值?在这种情况下的最佳做法?
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;
}
也没有必要捕捉异常,什么都不做,然后throw
,这样你可以删除整个try catch块。
答
首先,在巷道施工
catch (Exception e) {
throw;
}
是冗余一个,并且可以是消除。现在约为null
s。这里有两种情况 :
-
null
是错误价值,所以它应该是信号 -
null
是预期,普通价值,因此它应该是进行
所以你有(null
是错误的)
string errorMessage = AccountClient.GetAccount(id, out accountDetails);
// What's wrong: it's id which doesn't correspond to any detail
// (we expect id being s.t. AccountClient.GetAccount(id...) returns not null detail)
if (accountDetails == null)
throw new ArgumentException($"Incorrect id {id} which doesn't have any detail.",
nameof(id));
Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
或(null
是预期结果)
string errorMessage = AccountClient.GetAccount(id, out accountDetails);
if (accountDetails == null)
return null; // or any reasonable value, or just return, or create new Subscription
Subscription subscription = AccountProcessor.GetAccountDetails(accountDetails);
答
这取决于其中该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不是预期的值,那么就抛出一个异常。如果你所有的假设都被打破了,那么继续是没有意义的。简单地抛出该方法而不抛出可能最终会导致调用堆栈上的其他位置发生错误,从而更难以调试问题的原因。 – sstan
请注意,“break”不会“破坏函数”,它会突破周围的循环。 –
它看起来像'AccountClient.GetAccount'应该抛出一个异常,如果它失败,而不是返回一个错误消息。 – Lee