C# 有没有方法可以使方法防弹,例如,如果使用null参数调用该方法,那么它将给出异常?
我有一个函数:C# 有没有方法可以使方法防弹,例如,如果使用null参数调用该方法,那么它将给出异常?,c#,C#,我有一个函数: public int GetIntSetting(SET setting, int nullState) { // Get the setting value or nullState if it was not set var str = GetStringSetting(setting, nullState.ToString()); // Check if it's an integer var
public int GetIntSetting(SET setting, int nullState)
{
// Get the setting value or nullState if it was not set
var str = GetStringSetting(setting, nullState.ToString());
// Check if it's an integer
var isInt = int.TryParse(GetStringSetting(setting, nullState.ToString()), out int parsed);
// If integer then return else update settings and return nullState
if (isInt )
{
return parsed;
}
else
{
UpdateIntSetting(setting, nullState);
return nullState;
}
}
我想这样做,这样就不会有任何意外的机会从功能。如果您能给我一些建议,告诉我如何检查输入以及我应该考虑的其他方法,我将不胜感激。这不是一个真正的
C#
问题。这是关于什么是函数以及它应该如何操作的基础知识。从技术上讲,“函数”应该将所有输入参数视为不可变的,并返回一些值。“方法”可能有副作用。这里您使用的是一个C#
“方法”,但您可以将其视为一个函数,这往往会产生更干净的代码
编写函数时要记住的事项:
设置
未设置为整数值,请将其设置为空值
,并返回其值。我希望最终的方法不会超过几行(我在这里故意说方法,因为有一个副作用-如果它“未设置”,则更改设置
的值”)
你可能最终会得到一个方法,但我将反复强调函数的重要性,并降低单个函数的复杂度,您可以显著降低所需的单元测试用例覆盖率。尽管如此,这也是您问题的核心,您仍然希望尝试识别方法/函数的所有边缘用例。例如,假设我有以下精心设计的函数
bool IsPositive(int val) { return val > 0; }
有明显的>0
,和<0
,以及边缘大小写==0
。当前,val=0
将被视为负值,这可能是或可能不是所需的行为。此函数中只计算一个表达式,并且没有分支或循环,因此复杂度尽可能低,我们可以很容易地推断其行为
特别是在C#方面。您可以将所有内容包装在一个通用的
try/catch
块中,但这就是…什么是“最佳实践”?哦,是的,垃圾。如果您认为您可能会遇到完全超出您控制的某种异常(即非托管资源-db连接、http客户端连接等)然后您可以专门针对该异常。然后您可以使用try/catch
,但只捕获该特定异常。这当然意味着您已经确定了函数中可能的故障点
确定故障点的能力可以来自于理解您正在与之交互的数据结构,或者更常见的是,仅仅是经验(试错、调试)。这又一次超越了C#,回到了一般编程技能。与任何技能一样,它需要时间来培养,有些人天生就比其他人更擅长
现在让我们看看你的代码
public int GetIntSetting(SET setting, int nullState)
什么是SET
?现在我们将忽略SET
的行为可能封装在某个现有的.NET类中这一事实
{
// Get the setting value or nullState if it was not set
var str = GetStringSetting(setting, nullState.ToString());
您已检索到设置,或nullState.ToString()
,并将其保存在str
中。因此,在下一行中,您可以使用它,而不是再次计算它。然而,这里您只使用了一次值,因此我认为为变量分配内存没有意义,只需在下一行中取消引用它即可
// Check if it's an integer
var isInt = int.TryParse(GetStringSetting(setting, nullState.ToString()), out int parsed);
同样,没有理由将int.TryParse()
结果保存到变量中,它可以移动到if
表达式中。但是,您不需要TryParse
,因为如果未设置设置
,它将使用nullState.ToString()
,我们知道它必须是一个整数作为一个字符串,它将被成功解析。然后诀窍是找出GetStringSetting()
实际做了什么(代码气味)
局部地,您在if
块中返回,不需要else
因此,如果设置是一个整数值,则返回它,否则将其更改为nullState
并返回nullState
。但是我相信GetStringSetting()
的第二个参数是返回的值,如果第一个参数是“未设置”,则不管这意味着什么(null?null还是空?)。这意味着,如果未设置设置(GetStringSetting(setting,nullState.ToString())
),您可能已经在使用nullState
)
…但该设置可能已设置为非数字字符串(卷积边缘情况)。如果发生这种情况,该设置仍将是非数字字符串,但该方法的其余部分将使用nullState
进行操作
如果不了解更多其他代码,就很难说出您的边缘情况是什么,这往往是一种代码气味——需要其他代码了解方法/函数的行为(有时,在实践中,这是无法避免的)
此方法具有潜在的副作用。如果未设置设置
,或不是整数值,则其值将更改为空状态
// If integer then return else update settings and return nullState
if (isInt )
{
return parsed;
}
else
{
UpdateIntSetting(setting, nullState);
return nullState;
}
public int GetIntSetting(ISetting setting, int nullState)
{
int.Parse(GetStringSetting(setting, nullState.ToString()), out int parsed);
if(parsed == nullState)
{
UpdateIntSetting(setting, nullState);
}
return parsed;
}
public int GetIntSetting(ISetting setting, int nullState)
=> int.Parse(GetStringSetting(setting, nullState.ToString()), out int parsed);