帮助重构此C#函数
我编写的函数如下所示:帮助重构此C#函数,c#,C#,我编写的函数如下所示: bool IsDry(bool isRaining, bool isWithUmbrella) { if (isRaining) { if (isWithUmbrella) return true; else return false; } else return true; } 我需要检查一下,如果下雨,那么这个人需要带伞以保持干燥(不要笑,这只是一
bool IsDry(bool isRaining, bool isWithUmbrella) {
if (isRaining) {
if (isWithUmbrella)
return true;
else
return false;
}
else
return true;
}
我需要检查一下,如果下雨,那么这个人需要带伞以保持干燥(不要笑,这只是一个例子,我们的实际业务规则比这更严肃)
我如何重构它,因为现在它看起来很笨拙
谢谢你们的帮助,伙计们!=) 看起来您试图实施的业务规则是:
P IMPLIES Q
这在逻辑上等同于:
(NOT P) OR Q
因此,您可以简单地编写:
bool IsDry(bool isRaining, bool isWithUmbrella) {
return !isRaining || isWithUmbrella;
}
论(非)消极思维 根据谓词的不同,首先考虑否定也可能更简单
NOT (P IMPLIES Q)
我们现在替换上面的标识:
NOT ((NOT P) OR Q)
现在我们可以申请:
既然这是否定的,我们必须否定它才能回到积极的一面。一开始,双重否定似乎令人困惑,但回到示例,我们有:
bool IsDry(bool isRaining, bool isWithUmbrella) {
bool isWet = (isRaining && !isWithUmbrella);
return !isWet;
}
附加提示 下面是一些常见的
布尔表达式重写示例:
BEFORE | AFTER
________________________________________|________________________________________
|
if (condition == true) ... | if (condition) ...
________________________________________|________________________________________
|
if (condition == false) ... | if (!condition) ...
________________________________________|________________________________________
|
if (condition) { | return condition;
return true; |
} else { |
return false; |
} |
________________________________________|________________________________________
|
if (condition1) { | return (condition1 && condition2
if (condition2) { | && condition3);
if (condition3) { |
return true; |
} else { |
return false; |
} |
} else { |
return false; |
} |
} else { |
return false; |
} |
________________________________________|________________________________________
|
return (condition1 && !condition2) || | return condition1 != condition2;
(condition2 && !condition1); | // or condition1 ^ condition2;
请注意,C#中预定义的^
即使对于整数类型(即,它不是一个求幂运算符)也是相同的。预定义的和用于执行“短路”评估的
另见
这是一个真值表:
isRaining isWithUmbrella isWet isDry
true true false true
true false true false
false true false true
false false false true
有一个答案可能是:
var isWet = isRaining && !isWithUmbrella;
return !isWet;
我通常采用的方法是逐步细化。e、 g.如果出现以下情况,则首先消除内部缺陷:
bool IsDry(bool isRaining, bool isWithUmbrella) {
if (isRaining)
return isWithUmbrella;
else
return true;
}
然后将if崩溃
bool IsDry(bool isRaining, bool isWithUmbrella) {
return isRaining ? isWithUmbrella : true;
}
这是非常明显的
布尔没有训练{带伞返回}
:-)只需单击六下,即可将代码简化为一行
前三次点击将变形
if (isWithUmbrella)
return true;
else
return false;
进入
接下来的三次点击会改变
if (isRaining)
{
return isWithUmbrella;
}
else
return true;
进入
瞧,你完了
我如何重构这个
使用单元测试
真的。有两个布尔输入,所以您只需要四个单元测试就可以完全覆盖此方法
然后,由于已经有了完整的分支覆盖,您就可以对实现进行操作了。尝试一些似乎正确的方法(我发现在这种情况下编写一个真值表非常有帮助),测试将告诉您是否有错误的细节
作为进一步的好处,您可以将测试作为方法实际功能的文档永久保存。如果你选择了一个聪明的实现,比如奇特的布尔表达式,这尤其有用——如果你在努力遵循流程,你可以看看测试,然后看到“哦,我明白了——如果我通过了这个和这个,我就得到了这个。”首先从“else return…”语句中删除“else”,这样你就得到了:
if (isRaining) {
if (isWithUmbrella)
return true;
return false;
}
return true;
只要一点逻辑工作
if (isRaining) {
// return (isWithUmbrella) ?
// true :
// false;
return isWithUmbrella;
}
return true;
然后,您可以快速将其放入一个简单的return语句中
//return (isRaining) ? isWithUmbrella : true;
//return (!isRaining) ? true : isWithUmbrella;
return (!isRaining) || isWithUmbrella;
+1.再加上,!(isRaining&!IsWithumber)
相当于DeMorgan的(!isRaining | | IsWithumber)
。可能有助于获得您的答案投票。如果你解释p意味着q是描述数学。。。哦,55票不要紧:)哦,天哪,太糟糕了,OP没有注册。你应该多获得一枚大师徽章!虽然您的代码过于冗长,但我要提醒您不要在一行中使用两个以上的变量来编写逻辑表达式。随着单行逻辑表达式变得越来越复杂,重构它们变得越来越容易出错,因为它们可读性较差。例如,尝试添加ISindor作为另一个变量。请注意,对于人类来说,一行代码在飞行中解析变得更加困难。当重构简洁并不意味着可读性时,请记住这一点;否则返回false代码>反模式@米奇:多亏了那次投票,我想我在代表系统上发现了一个潜在的漏洞。现在在meta上发布。@Null,这是一场人气竞赛,你不知道吗+1对你来说无效。开发软件和缺乏幽默感是造成痛苦的一个必然原因。如果你解释了为什么ReSharper会有帮助,这个答案可能会很有用。我已经添加了一个解释。感谢您的反馈。为什么不只是:return(!(isRaining&&!iswithumbrane))代码>?我试图通过给内部布尔表达式一个明确的含义来表示意图。希望它能让后来带着isAlreadyWetAnyway旗帜的人更容易地把它放在正确的位置。+1!这还将从调用方的角度显示用法,这有助于设计。if(IsDry(true,false))在客户机代码中很难解释-布尔值代表什么?也许这可能是一个具有IsRaining和HasUmbrella属性的类的实例方法。
return isWithUmbrella;
if (isRaining)
{
return isWithUmbrella;
}
else
return true;
return !isRaining || isWithUmbrella;
if (isRaining) {
if (isWithUmbrella)
return true;
return false;
}
return true;
if (isRaining) {
// return (isWithUmbrella) ?
// true :
// false;
return isWithUmbrella;
}
return true;
//return (isRaining) ? isWithUmbrella : true;
//return (!isRaining) ? true : isWithUmbrella;
return (!isRaining) || isWithUmbrella;