是否有更优雅的方法?我真的觉得这很丑。
private static string InsertMethodNameHere( bool hasCondition1, bool hasCondition, bool hasCondition3)
{
if (!hasCondition1 && !hasCondition2 && !hasCondition3)
return "0";
if (hasCondition1 && !hasCondition2 && !hasCondition3)
return "1";
if (!hasCondition1 && hasCondition2 && !hasCondition3)
return "2";
if (hasCondition1 && hasCondition2 && !hasCondition3)
return "3";
if (!hasCondition1 && !hasCondition2 && hasCondition3)
return "4";
if (hasCondition1 && !hasCondition2 && hasCondition3)
return "5";
if (!hasCondition1 && hasCondition2 && hasCondition3)
return "6";
if (hasCondition1 && hasCondition2 && hasCondition3)
return "7";
throw new Exception("Unable to determine.");
}
#1 楼
private static string InsertMethodNameHere(bool hasCondition1, bool hasCondition2, bool hasCondition3)
{
return ((hasCondition1 ? 1 : 0) +
(hasCondition2 ? 2 : 0) +
(hasCondition3 ? 4 : 0)).ToString(CultureInfo.InvariantCulture);
}
如果您想要一个更通用的解决方案,则可以编写一个扩展方法,将布尔变量列表转换为int变量:
public static int ToInt(this IEnumerable<bool> bools)
{
return bools.Select((t, i) => (t ? 1 : 0) << i).Sum();
}
评论
\ $ \ begingroup \ $
很好,非常整洁且可读。
\ $ \ endgroup \ $
– Nadir Sampaoli
2012年6月26日19:40
\ $ \ begingroup \ $
我喜欢这个它看起来干净简单。谢谢!
\ $ \ endgroup \ $
–汤姆·奥尔德曼(Tom Alderman)
2012年6月27日上午11:17
\ $ \ begingroup \ $
因为我的答案一直在底部,这是一个很好的答案,仅此而已;您可以使用“ params”关键字并将bools设置为数组,然后用户不必设置实际的IEnumerable bools。您可以将其设置为此方法的重载,然后可以将布尔值列表或一组不同的变量转换为int值。
\ $ \ endgroup \ $
– KeithS
2012年7月13日15:10
#2 楼
您正在使用3个单独的布尔变量表示某种状态。最好使用带有标志的枚举来表示这种状态。然后,无需进行复杂的测试即可确定您所处的状态。然后,您可以组合标志以表示每个单独的状态,然后将其关闭。[Flags]
public enum MyState
{
// your flags
Default = 0x00,
Condition1 = 0x01,
Condition2 = 0x02,
Condition3 = 0x04,
// your state
State0 = Default,
State1 = Condition1,
State2 = Condition2,
State3 = Condition3,
State4 = Condition1 | Condition2,
State5 = Condition1 | Condition3,
State6 = Condition2 | Condition3,
State7 = Condition1 | Condition2 | Condition3,
}
private static void DispatchMethod(MyState state)
{
switch (state)
{
case MyState.State0:
// do something for state 0
break;
case MyState.State1:
// do something for state 1
break;
case MyState.State2:
// do something for state 2
break;
case MyState.State3:
// do something for state 3
break;
case MyState.State4:
// do something for state 4
break;
case MyState.State5:
// do something for state 5
break;
case MyState.State6:
// do something for state 6
break;
case MyState.State7:
// do something for state 7
break;
}
}
您仍然可以使用简单的按位逻辑来设置和清除单个标志。 br />
评论
\ $ \ begingroup \ $
只是警告,在这样的枚举上调用ToString()不会产生您可能期望的结果。由于存在重叠的值,因此默认实现将返回可能适用的多个值。
\ $ \ endgroup \ $
–杰夫·梅卡多(Jeff Mercado)
2012年6月26日14:04
\ $ \ begingroup \ $
最好将“标志”放在一个单独的枚举中,以避免重叠的ToString()?
\ $ \ endgroup \ $
–本·科特雷尔
2012年6月26日17:48
\ $ \ begingroup \ $
我认为这是问题,但问题是您必须映射出值,以便它们在类型之间相对应。但是无论如何您都不一定需要ToString()返回的结果,您可以通过其他方式获取值的名称。而且实际上,我认为字符串表示形式并不需要太多,我们只关心值。
\ $ \ endgroup \ $
–杰夫·梅卡多(Jeff Mercado)
2012年6月26日18:11
#3 楼
使用Jeff的答案中的MyState
标志枚举,您可以像下面这样在Scroog1的答案中进行操作:br />
另请参见:http://weblogs.sqlteam.com/mladenp/archive/2007/01/12/57541.aspx
#4 楼
private static string InsertMethodNameHere(params bool[] conditions)
{
conditions.Select((x,i)=>Convert.ToByte(x) << i).Sum().ToString();
}
在您的特定情况下,它会立即消失,这使IMO比Scroog更好,因为他要求用户将条件转换为IEnumerable格式。
params
关键字很漂亮。此函数(像许多答案一样)假定所需状态始终是条件的大端位数组的串联。
评论
我可能会问你为什么觉得丑陋?对我来说,它看起来很可读。我想它是可读的,但是,我不喜欢该方法中的这么多返回。
我想这是一个偏爱的问题,但必须注意,美通常不是软件质量的一个方面。就可读性而言,我个人更喜欢原始答案,而不是公认的答案。