C# 不带开关的交替方式/If else-C

C# 不带开关的交替方式/If else-C,c#,linq-to-sql,coding-style,C#,Linq To Sql,Coding Style,我有下面的C代码,这是代码中基于功能编写if/else或switch的一般场景 在同一个函数中,我写了多行代码,这增加了代码的复杂性 如果没有其他方法,是否有其他更好的方法可以实现?欢迎提出任何其他建议 //Sample Piece of code to highlight my scenario. may have syntax errors IEnumerable<lst> fnc(string category) { using(Context sample = new

我有下面的C代码,这是代码中基于功能编写if/else或switch的一般场景

在同一个函数中,我写了多行代码,这增加了代码的复杂性

如果没有其他方法,是否有其他更好的方法可以实现?欢迎提出任何其他建议

//Sample Piece of code to highlight my scenario. may have syntax errors
IEnumerable<lst> fnc(string category)
{
    using(Context sample = new Context())
    {
        if (category == "A")
        {
            return from T1  in  sample.TableName 
                   join T2 in sample.A on T1.id = T2.id
                   where cat= category
                   select T1
        }
        else if (category == "B")
        {
            return from T1  in  sample.TableName 
                   join T2 in sample.B on T1.Eid = T2.id
                   where cat= category
                   select T1
        }
        else if (category == "C")
        {
            return from T1  in  sample.TableName 
                   join T2 in sample.C on T1.id = T2.id
                   where cat= category
                   select T1
        }
        // ...
        else if (category == "I")
        {
            return from T1  in  sample.TableName 
                   join T2 in sample.I on T1.id = T2.id
                   where cat= category
                   select T1
         }
         else
         { /* return ... */ }
    }
}

谢谢。

您可以建立一个字典来存储条件:

var array = new[] {10, 20, 30};
var conditions = new Dictionary<string, Func<int, bool>>
{
    {"A", input => input > 10},
    {"B", input => input > 20}
};

if (conditions.ContainsKey(category))
{
    return array.Where(conditions[category]);
}
else
{
    // else :>
}
int必须替换为存储在可枚举表中的类型。

您可以为LINQ to对象创建字典或字典,并使用它而不是if/else或switch/case:


您可以使用。创建一个包含所有条件的数组。然后根据“Category”条件获取数组索引,并将其用于LINQ表达式

正如您所提到的,对于不同的条件,您有不同的联接,但仍然可以使用字符串键将所有查询放入字典中,类似于:

IEnumerable<lst> fnc(string category)
{
    return JoinByCategory(sample.TableName, category)
             .Where(t1 => t1.cat == category);
}

private IQueryable<T1> JoinByCategory(IQueryable<T1> outer, string category)
{
   switch(category)
   {
      case "A": return outer.Join(sample.A, t1=> t1.id, a=> a.id, (t1,a)=> t1);
      case "B": return outer.Join(sample.B, t1=> t1.Eid, b=> b.id, (t1,b)=> t1);
      ...
      default:
         throw new ArgumentException();
   }
}
    private static Dictionary<string, Func<DataContext, IEnumerable<lst>>> functions = new Dictionary<string, Func<DataContext, IEnumerable<lst>>>() 
    { 
        {"A", 
         delegate(DataContext dbCtx)
         {
            return new List<lst>(); // your query here...
         }
        },
        {"B", 
         delegate(DataContext dbCtx)
         {
            return new List<lst>();
         }
        },
        {"C", 
         delegate(DataContext dbCtx)
         {
            return new List<lst>();
         }
        }
    };

    public IEnumerable<string> fnc(string category)
    {
        if (!(functions.ContainsKey(category)))
        {
            throw new NotImplementedException();
        }

        using(Context sample = new Context()
        {
            return functions[category].Invoke(sample);
        }
    }

希望对您有所帮助……

切换命令可以替换为地图扩展方法:

return externalCode
    .Map("A", from T1 in sample.TableName
            join T2 in sample.A on T1.id = T2.id 
            where cat = category
            select T1)
    .Map("B", from T1 in sample.TableName
            join T2 in sample.B on T1.Eid = T2.id 
            where cat = category
            select T1)
    .Map("C", from T1 in sample.TableName
            join T2 in sample.C on T1.id = T2.id 
            where cat = category
            select T1)
    .Map("I", from T1 in sample.TableName
            join T2 in sample.I on T1.id = T2.id 
            where cat = category
            select T1)
    .Else(...)

更多示例和资料来源:。

显示条件会让我们更清楚什么是cond I、cond A等?您是否在一个位置打开了此类别,或者在应用程序中重复了此类别?@Peru请显示至少两个linq查询,以便我们了解在您不更改条件的情况下发生了什么。您将连接更改为sql。对于linq,这可能无法在所有情况下工作。我已根据条件更新了我的代码和连接更改。使用上述方法是否可行?你能分享一些代码吗?如果是的,你把开关从fnc移到另一个函数:-@Grundy好吧,我把变化的部分从保持不变的代码中移出。是的,当我们处理固定的小案例时,我更喜欢切换到字典。切换的另一个很好的选择是多态性,但我认为在这种情况下引入类层次结构是不值得的:@SergeyBerezovskiy谢谢你的回答。我想我需要更多的时间来理解这些概念:。有什么建议或文章可以让我从这些基础知识开始吗?@Peru msdn:-全部关于IQueryable@Peru,正如格伦迪所说,这一切都是关于IQueryable的。您可以使用查询语法编写查询,编译器会将查询语法转换为方法语法。当您必须基于某些条件组合查询时,方法语法非常方便。看一看,我想你指的是函数[类别]的确。。。对不起,我使用vb.net已经有一段时间了,差点忘了c语法,真是太遗憾了
return externalCode
    .Map("A", from T1 in sample.TableName
            join T2 in sample.A on T1.id = T2.id 
            where cat = category
            select T1)
    .Map("B", from T1 in sample.TableName
            join T2 in sample.B on T1.Eid = T2.id 
            where cat = category
            select T1)
    .Map("C", from T1 in sample.TableName
            join T2 in sample.C on T1.id = T2.id 
            where cat = category
            select T1)
    .Map("I", from T1 in sample.TableName
            join T2 in sample.I on T1.id = T2.id 
            where cat = category
            select T1)
    .Else(...)