【问题标题】:c# if else then statement with LINQc# if else then 语句与 LINQ
【发布时间】:2012-01-20 21:59:43
【问题描述】:

我有以下代码:

if (intval == 0)
{
    var result = (from dm in datacontext.Trk
                  where dm.ID == 0
                  select dm);
}
else
{
   var result = (from dm in datacontext.Trk
                 where dm.ID != 0
                 select dm);
}

if (result != null)
{
    // do something
}

if (result!= null) 的结果下方有一条粗暴的线,表示名称结果在当前上下文中不存在。

不知道如何解决这个问题。我最初尝试var result = null,但 C# 不喜欢那样。

【问题讨论】:

  • 在块 { } 中声明的变量仅限于此块。

标签: c# linq inferred-type


【解决方案1】:

变量仅限于声明它的块。所以你有两个results,一个在if块中,一个在else块中,它们是不同的,在它们的块之外不可见。

你需要在块外定义变量,但是你需要明确类型,因为C#编译器需要直接赋值表达式来推断var关键字的类型。

但是,我建议重新考虑您的代码并执行以下操作:

var result = from dm in datacontext.Trk
             where ((intval == 0) ? dm.ID == 0 : dm.ID != 0)
             select dm;

if (result.Any())
{
   // do something
}

还请注意,result 永远不会是 null,因此,我已将其替换为 Any,但我相信这不是问题的要点。

【讨论】:

  • 这很好,应该在整个网络上共享,只有对任何条件 where 语句的好答案。谢谢!
【解决方案2】:

这样的事情怎么样:

    var result = 
        intval == 0 
            ?(from dm in datacontext.Trk where dm.ID = 0 select dm) 
            :(from dm in datacontext.Trk where dm.ID != 0 select dm);

    if(results.Any())
    {
        ...
    }

【讨论】:

    【解决方案3】:

    需要在if语句前声明result

    object result = null;
    
    if (intval = 0)
    {
       result = (from dm in datacontext.Trk
                     where dm.ID = 0
                     select dm);
    
    }
    else
    {
       result = (from dm in datacontext.Trk
                     where dm.ID != 0
                     select dm);
    
    
     }
    
     if (result != null)
     {
    
      // do something
    
     }
    

    或者您可以将 var 声明保留在其他变体中:

    var result = (from dm in datacontext.Trk
                     where dm.ID != 0
                     select dm);
    
    if (intval = 0)
    {
       result = (from dm in datacontext.Trk
                     where dm.ID = 0
                     select dm);
    
    }
    
    if (result != null)
    {
       // do something
    
    }
    

    现在您应该找到一种方法来更改 if 或完全删除它,因为此时 result 不能是 null

    【讨论】:

    • LINQ 查询的结果不是 IEnumerable 吗?不是对象?
    • @hanzolo:是的,确实如此,但为了概括起见,我决定在这种情况下保持中立,因为他使用的是 var。
    • @hanzolo any IEnumerable 也是一个对象。
    • @Tudor,我无法理解性能问题。 result = (from dm in datacontext.Trk where dm.ID =!= 0 select dm); 我认为这是在对其进行迭代时真正执行的。
    • @hanzolo 虽然确实任何 IEnumerable 也是一个对象,但这是一个相当无用的事实。您可以将 IEnumerable 分配给对象引用,但是一旦它存在,您就不能用它做太多价值;如果不将其转换回 IEnumerable,则无法枚举它或对其调用任何 linq 方法。
    【解决方案4】:

    您可以与主查询分开执行 where:

    var result = from dm in datacontext.Trk select dm;
    if (intval == 0)
    {
        result = result.Where(dm => dm.ID == 0);
    }
    else
    {
        result = result.Where(dm => dm.ID != 0);
    }
    
    if (result.Any())
    {
        // do something
    }
    

    【讨论】:

      【解决方案5】:

      您需要在第一个 if-else 之前声明结果变量。

      您还需要在第二个 if 语句中的条件周围加上括号。

      【讨论】:

        【解决方案6】:

        这段代码也会导致问题:

        if (value == 0)
        {
             int result = 1;
        }
        else
        {
             string result = "testing";
        }
        
        if (result != 1)
        {
             // do something
        } 
        

        第一次结果是int,第二次我声明了string,第三次result 未声明。它们可以具有不同类型的原因是因为前两个声明属于不同的范围。每个{ ... } 都有自己的范围。

        如果你想在作用域之间共享一个变量,你需要在外面声明它。但是现在,由于三个地方都使用了同一个变量,所以会出现类型不匹配的编译错误:

        int result;
        
        if (value == 0)
        {
            result = 1;
        }
        else
        {
            result = "testing"; // type error here
        }
        
        if (result != 1)
        {
             // do something
        } 
        

        【讨论】:

          【解决方案7】:
          List<TypeOfDm> dmList; // <=== Declare dmList outside of block statements.
          if (intval == 0) { // <=== Use "==" for comparision, "=" is assignement.
              dmList = datacontext.Trk
                  .Where(dm =>  dm.ID == 0)
                  .ToList();
          } else { 
              dmList = datacontext.Trk
                  .Where(dm =>  dm.ID != 0)
                  .ToList();
          } 
          if (dmList.Count != 0) { 
            // do something 
          } 
          

          注意,使用您的代码,您的结果将始终为非空。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-08-02
            • 2011-05-11
            • 2016-08-30
            • 2015-11-18
            • 1970-01-01
            相关资源
            最近更新 更多