C# 循环中的嵌套条件

C# 循环中的嵌套条件,c#,C#,给定以下代码,是否有更好的方法来构造此结构 foreach(Thing item in SomeRandomList) { bool firstCondition = CalculateBool(item, someValue); bool secondCondition = CalculateBool(item, someOtherValue); //General things are done... if(firstCondition || secondC

给定以下代码,是否有更好的方法来构造此结构

foreach(Thing item in SomeRandomList)
{
    bool firstCondition = CalculateBool(item, someValue);
    bool secondCondition = CalculateBool(item, someOtherValue);

    //General things are done...
    if(firstCondition || secondCondition)
    {
        //semi-specific things are done...
        if(firstCondition)
        {
            //specific things are done...
        } 
        else
        {
            //specific things are done...
        }
    }
}
此外,如果存在更多条件,即3:

foreach(Thing item in SomeRandomList)
{
    bool firstCondition = CalculateBool(item, someValue);
    bool secondCondition = CalculateBool(item, someOtherValue);
    //imagine as many more as you want.
    bool nthCondition = CalculateBool(item, lastOtherValue);

    //General things are done...
    if(firstCondition || secondCondition || nthCondition)
    {
        //semi-specific things are done...
        if(firstCondition)
        {
            //specific things are done...
        } 
        else if(secondCondition)
        {
            //specific things are done...
        }
        else
        { 
            //specific things are done...
        }
    }
}

如果你能在特定的事情之后再做半特定的事情,你可以尝试以下方法:

bool anyTrue = true;

if (firstCondition)
{
    // Specific things
}
else if (secondCondition)
{
    // Specific things
}
else
{
    // Specific things
    anyTrue = false;
}

if (anyTrue)
{
    // Semi-specific things
}
我不知道它是否一定更好,但它是不同的

或者,我并不完全了解C#3.0和新奇的LINQ产品,但如果它的表现力足够强,您可以尝试(伪代码):


如果你能在特定的事情之后再做半特定的事情,你可以尝试以下方法:

bool anyTrue = true;

if (firstCondition)
{
    // Specific things
}
else if (secondCondition)
{
    // Specific things
}
else
{
    // Specific things
    anyTrue = false;
}

if (anyTrue)
{
    // Semi-specific things
}
我不知道它是否一定更好,但它是不同的

或者,我并不完全了解C#3.0和新奇的LINQ产品,但如果它的表现力足够强,您可以尝试(伪代码):

是的:多态性

从公共基础派生出
东西(或定义所有
东西实现的接口)

否则,将条件测试代码移动到
Thing
上的方法中

从公共基础派生出
东西(或定义所有
东西实现的接口)


否则,将条件测试代码移动到
Thing

上的方法中,我可能无法正确回答问题,如果函数的返回类型为
bool
而不是
n
结果,则只能得到
2
结果,除非是,否则也可能返回null

所以

我会的

关于管理大型
if/else
组合?一种方法是使用语句,这可以提高可读性

但是在任何情况下,一个方法应该总是有最少可能的决策路径,这被称为


如果发生这种情况,将代码拆分为更合适的方法

我可能无法正确回答问题,如果函数的返回类型为
bool
not
n
结果,则只能得到
2
结果,除非是,否则也可能返回null

所以

我会的

关于管理大型
if/else
组合?一种方法是使用语句,这可以提高可读性

但是在任何情况下,一个方法应该总是有最少可能的决策路径,这被称为


如果发生这种情况,请将代码拆分为更合适的方法

我将使用一些LINQ来使用中间查询,以帮助减少循环中的逻辑:

// Get condition in the query.
var query =
    from item in SomeRandomList
    let condition1 = CalculateBool(item, someValue1)
    let condition2 = CalculateBool(item, someValue2)
    ...
    let conditionN = CalculateBool(item, someValueN)
    where
        condition1 || condition2 || ... || conditionN
    select new { Item = item, 
        Condition1 = condition1, Condition1 = condition2, ...
        ConditionN = conditionN };

foreach(var item in query) 
{ 
    //semi-specific things are done... 
    if(firstCondition) 
    { 
        //specific things are done... 
    }  
    else 
    { 
    //specific things are done... 
    } 
}
希望这将极大地减少循环中的代码量

但在我看来,对于SomeRandomList中的每个项目,都有一系列值被传递到CalculateBool。如果是这种情况,那么您可以很容易地生成一个查询,对该查询进行交叉连接和筛选:

// Get all valid items across all values.
var query =
    from item in SomeRandomList
    from value in someValues
    where CalculateBool(item, value)
    select { Item = item, Value = value };

// Iterate and process.
foreach (var item in query)
{
    // Use item.Item and item.Value.
    // Specifically, use item.Value to perform a lookup
    // in a map somewhere to determine the course of action
    // instead of a giant switch statement.
}

这会起作用,因为您的条件表示每个项只设置一个值。

我会使用一些LINQ来使用中间查询,以帮助减少循环中的逻辑:

// Get condition in the query.
var query =
    from item in SomeRandomList
    let condition1 = CalculateBool(item, someValue1)
    let condition2 = CalculateBool(item, someValue2)
    ...
    let conditionN = CalculateBool(item, someValueN)
    where
        condition1 || condition2 || ... || conditionN
    select new { Item = item, 
        Condition1 = condition1, Condition1 = condition2, ...
        ConditionN = conditionN };

foreach(var item in query) 
{ 
    //semi-specific things are done... 
    if(firstCondition) 
    { 
        //specific things are done... 
    }  
    else 
    { 
    //specific things are done... 
    } 
}
希望这将极大地减少循环中的代码量

但在我看来,对于SomeRandomList中的每个项目,都有一系列值被传递到CalculateBool。如果是这种情况,那么您可以很容易地生成一个查询,对该查询进行交叉连接和筛选:

// Get all valid items across all values.
var query =
    from item in SomeRandomList
    from value in someValues
    where CalculateBool(item, value)
    select { Item = item, Value = value };

// Iterate and process.
foreach (var item in query)
{
    // Use item.Item and item.Value.
    // Specifically, use item.Value to perform a lookup
    // in a map somewhere to determine the course of action
    // instead of a giant switch statement.
}

这是可行的,因为您的条件表示每个项只设置一个值。

我喜欢有一个
谓词
及其相关
操作
字典的方法。我在这里回答了一个类似的问题:

要针对您的问题稍微修改它,请执行以下操作:

Dictionary<Predicate<Something>, Action> mappings = {{...}}
bool shouldDoAnything = mappings.Keys.Aggregate(true, (accum, condition) => 
    accum || condition);

if (shouldDoAnything)
{
   //do semi-specific things

   foreach(DictionaryEntry<Predicate<Something>, Action> mapping in mappings)
   {
      if (mapping.Key(input))
      {
         mapping.Value(); //do specific things
         break;
      }
    }
}
字典映射={{…}
bool shouldDoAnything=mappings.Keys.Aggregate(true,(acum,condition)=>
累积条件);
如果(应该做任何事)
{
//做半特定的事情
foreach(映射中的字典入口映射)
{
if(映射键(输入))
{
mapping.Value();//执行特定的操作
打破
}
}
}

我喜欢有一个
谓词
及其相关
动作
字典的方法。我在这里回答了一个类似的问题:

要针对您的问题稍微修改它,请执行以下操作:

Dictionary<Predicate<Something>, Action> mappings = {{...}}
bool shouldDoAnything = mappings.Keys.Aggregate(true, (accum, condition) => 
    accum || condition);

if (shouldDoAnything)
{
   //do semi-specific things

   foreach(DictionaryEntry<Predicate<Something>, Action> mapping in mappings)
   {
      if (mapping.Key(input))
      {
         mapping.Value(); //do specific things
         break;
      }
    }
}
字典映射={{…}
bool shouldDoAnything=mappings.Keys.Aggregate(true,(acum,condition)=>
累积条件);
如果(应该做任何事)
{
//做半特定的事情
foreach(映射中的字典入口映射)
{
if(映射键(输入))
{
mapping.Value();//执行特定的操作
打破
}
}
}

在任何情况下,外部条件似乎都是多余的。如果您希望针对特定的条件组合执行特定的行,那么您就只能吃意大利面条了。但就你的例子而言,Simon是对的——你的条件是相互排斥的,而且优先级很高,所以一开始就不要麻烦或把它们放在一起。你没有提供足够的信息来说明你想要完成什么,那么我们怎么说有没有更好的方法来组织你的代码呢?@Simon,您是否希望
//完成半特定的事情…
在剩余的
if
语句中重复,一般问题通常是发现一般原则而不是特定解决方案的唯一方法。在任何情况下,外部条件似乎都是多余的。如果你想在某些条件组合下执行特定的行,你就只能吃意大利面条。但就你的例子而言,Simon是对的——你的条件是相互排斥的,而且优先级很高,所以一开始就不要麻烦或把它们放在一起。你没有提供足够的信息来说明你想要完成什么,那么我们怎么说有没有更好的方法来组织你的代码呢?@Simon,您是否希望
//完成半特定的事情…
在剩余的
if
语句中重复?Great Turtle,一般问题通常是发现问题的唯一方法