是否有更优雅的方法?我真的觉得这很丑。

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关键字很漂亮。此函数(像许多答案一样)假定所需状态始终是条件的大端位数组的串联。