[英]Should I use a variable for a switch statement or a return statement when using a switch in a property to retrieve a value?
我应该在返回结果之前保存switch语句的结果吗? 还是应该在获得值时在开关中返回该值? 有没有一种更好的风格?
带有临时变量:
public double xMax {
get {
double val = 0.00f;
switch(x_option) {
case 0:
val = priMax;
break;
case 1:
val = rfMax;
break;
case 2:
val = pwMax;
break;
}
return val;
}
}
带有return语句:
public double xMax {
get {
double val = 0.00f;
switch(x_option) {
case 0:
return priMax;
case 1:
return rfMax;
case 2:
return pwMax;
}
}
}
是否存在性能差异和/或清理?
我个人更喜欢第二种形式。 它立即表明,一旦您返回return语句,就完成了。 使用额外的变量版本,您必须查看其余的代码,看是否还会发生其他事情。
在C中,围绕单个返回点的教条是有意义的,在C中,您想确保已完成所有手动清理等工作-但在当今世界中, 无论如何您都必须考虑异常的可能性以及垃圾收集器处理大多数清理工作,并try/finally
处理其余工作,我发现在很多情况下,坚持单个出口点会使代码难以阅读,尤其是在开始时就可以确定结果的情况下方法的结果(例如“如果输入字符串为空,则结果始终为0-因此只需将其返回)即可。
编辑:只是要清楚一点,在您的情况下,我认为这没有太大的区别。 但这是单点返回变得凌乱的代码类型:
public int DoSomething(string input1, string input2)
{
// First simple case
if (input1 == null || input2 == null)
{
return -1;
}
// Second simple case
int totalLength = input1.Length + input2.Length;
if (totalLength < 10)
{
return totalLength;
}
// Imagine lots of lines here, using input1, input2 and totalLength
// ...
return someComplicatedResult;
}
有了一个收益点,它将变成:
public int DoSomething(string input1, string input2)
{
int ret;
// First simple case
if (input1 == null || input2 == null)
{
ret = -1;
}
else
{
// Second simple case
int totalLength = input1.Length + input2.Length;
if (totalLength < 10)
{
ret = totalLength;
}
else
{
// Imagine lots of lines here, using input1, input2 and totalLength
// ...
ret = someComplicatedResult;
}
}
return ret;
}
我绝对希望阅读第一种形式,而不是第二种形式:
好吧,最重要的是不要混在一起。
第一种形式的动机是它具有从吸气剂的单一出口。 如果代码比示例中的复杂,那可能会有用,但是在这样的简单示例中,它实际上并不重要。
只要代码和示例中的代码一样简单,第二种形式的简单性就是一个很好的论据。
您的第二个示例现在无法编译,因为代码可以到达属性的末尾而不返回任何内容。 在第一种情况下,您可以在开关之前将变量设置为默认值,对于第二种情况,应在开关中使用默认选项,并且根本不需要该变量:
public double xMax {
get {
switch(x_option) {
case 0:
return priMax;
case 1:
return rfMax;
case 2:
return pwMax;
default:
return 0d;
}
}
}
这是一个品味问题,但我希望在可能的情况下只有一个回报点 。 调试起来更容易,让您在使用代码协定时更清楚地检查前后。
这个问题已经两代了。 但是我会回答的,因为这个问题过去也困扰着我。
您正在查看的是: 语法A和语法B。
您应该看什么: 整个代码中语法的一致性。
选择一种样式并坚持下去。 这可以由个人选择,团队的选择,老板的选择等决定。烦恼表现,直到遇到瓶颈,才把车推上马。
作为代码和复杂性累积的普遍结果,如果您遇到switch语句,那么有人在某个地方写了不好的代码,并试图用一个代码球处理很多事情。
例子:一个返回JSON的API调用,该JSON返回一个数组中的5个不同值,您需要弄清楚如何处理它或根据需要选择哪些数据。
大多数情况下,一旦有多次返回或ifs的可能性,就应将代码分成几小段。
以Jon Skeet的代码为例:
public int DoSomething(string input1, string input2)
{
int ret;
// First simple case
if (input1 == null || input2 == null)
{
ret = -1;
}
else
{
// Second simple case
int totalLength = input1.Length + input2.Length;
if (totalLength < 10)
{
ret = totalLength;
}
else
{
// Imagine lots of lines here, using input1, input2 and totalLength
// ...
ret = someComplicatedResult;
}
}
return ret;
}
private int someComplicatedTask(string input1, string input2){ // Second simple case int ret = 0; int totalLength = input1.Length + input2.Length; if (totalLength < 10) { ret = totalLength; } else { // Imagine lots of lines here, using input1, input2 and totalLength // ... ret = someComplicatedResult; } return ret; } public int DoSomething(string input1, string input2) { return input1 == null || input2 == null ? -1 : someComplecatedTask(...); }
这应该使您感到纳闷:“当输入有可能为空时,为什么要调用DoSomething?”。
请注意问题尚未解决。 我所要做的就是使代码看起来更好。
这是有关条件的处理方式:
空输入的条件将移至消毒功能。 或仅在输入不为null时调用。
... if(input1 != null && input2 != null){ output = DoSomething(input1, input2); } ... public int DoSomething(string input1, string input2) { int len = input1.Length + input2.Length; return len < 10 ? len : someComplecatedTask(input1, input2); } private int someComplicatedTask(string input1, string input2){ // Imagine lots of lines here, using input1, input2 // ... return someComplicatedResult; }
因此,代码现在看起来更易于管理。 代码只能走两种途径,一切都很好。
现在,让我们看一下您的第一个代码段。
public double xMax { get { double val = 0.00f; switch(x_option) { case 0: val = priMax; break; case 1: val = rfMax; break; case 2: val = pwMax; break; } return val; } }
在我头顶上,这很糟糕,原因有两个:
1.在将来的某个时间,x_option获得另一个值,您将在每一次get {}下进行适当的更改。
2. Get {}应该很简单。 Set {}应包含用于设置适当值的条件。
所以代码应该看起来像这样:
public double xMax { set { double val = 0.00f; switch(value) { case 0: val = priMax; break; case 1: val = rfMax; break; case 2: val = pwMax; break; } xmax = value * val; // say // This makes break better in switch. } get { return xmax; } }
由于在处理完案件后,您可以执行更多(对于所有案件而言是常见的)操作,所以这比返回更好。 这个示例相对于获得一个更好,因为在设置时您不知道值,因此需要决策树。
但是,在获取对象时,您完全知道对象包含的内容,并高兴地返回所要求的内容。
现在,您的第二个代码示例完全没有意义。 决定返回什么不是对象的责任。 它应该返回它的pronto。
而且在设置时,无论如何您都不应强行返回。
我希望这可以消除一些疑问,并提出更多问题,因为还有很多东西需要学习。
在华沙军事技术大学的第一个编程班上,Eng博士。 ZbigniewWesołowski指出,该函数只能有一个返回点。 它是ANSI-C编程的简介,但是他也告诉我们,无论我们将要开发哪种语言,我们都永远不要忘记这是一条通用规则。声明如果一个人尝试甚至使用一次goto语句,返回函数中间或修改for循环内的迭代器,那么他将永远不会通过考试。
无论是否回到中间,这都是一个古老的难题。 有人声称它使代码更清晰,而另一些人则认为它不美观,应避免使用。 根据我的经验,我注意到,多次返回通常发生在Java代码中,而C,C ++和C#程序员则宁愿避免这种情况。 这不是规则,只是观察。
另一个观察结果是Java语言鼓励使用紧凑的语法。 Java IDE(例如eclipse)通常将默认格式设置为将左大括号放在同一行(只是一个简单的示例)。 多次返回与该方法保持一致,从而可以进一步压缩代码。
相反的Visual Studio将换行符作为唯一字符放在新行上。 它鼓励使用清晰,粗体的语法,包括长文件,许多空白或单个字符行。 我不知道哪一种更好。
基本上,我在大学和家庭课堂上都编写C#。 然后,我更喜欢带有空行的长文件。
在我的公司中,我编写Java代码,然后选择习惯的更紧凑的样式。 在公司中,我们使用checkstyle通过统一样式保持良好的代码质量。 并且经过多年的公司生存,一直存在支票风格的规则,根本禁止多次退货。
我在stackoverflow上看到过一篇文章,其中有人指出它会对性能产生影响。 在一个答案中,他得到了一个简单的基准测试结果。 实际上,并没有太大的区别。
在我的编码实践中,我宁愿避免多次回报。 但是您的总体决定将取决于您的个人品味,经验,习惯,信念,甚至是质量要求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.