【问题标题】:How can I explicitly type these variables in a LINQ statement?如何在 LINQ 语句中显式键入这些变量?
【发布时间】:2016-08-03 18:52:10
【问题描述】:

我正在以this answer 中描述的方式解析 csv 文件;效果很好。

    public static List<string> MatchedLines(string[] MyArray)
    {
        List<string> csvFile = FileReadLinestoList(@"C:\Temp\MyFile.csv");
        //This doesn't work! //var lines = new IEnumerable<string>{from line in csvFile where line.Split(',')[0] == MyArray[0] && line.Split(',')[1] == MyArray[1] select line};
        var lines = from line in csvFile where line.Split(',')[0] == MyArray[0] && line.Split(',')[1] == MyArray[1] select line;
        return lines.ToList();
    }

但是我不喜欢使用'var',除非变量类型很清楚,在这种情况下它们不是。如何在显式声明“行”和“行”类型的同时编写此语句?

【问题讨论】:

  • 正如已删除的答案指出的那样,您可以将鼠标悬停在 Visual Studio 中的 var 上,并查看编译时将分配给变量的实际类型。

标签: c# linq csv


【解决方案1】:

您不能直接创建接口的实例,因此new IEnumerable&lt;string&gt; 根本不起作用。但是您仍然可以通过指定如下类型将变量键入为接口:

IEnumerable<string> lines = from line in csvFile where line.Split(',')[0] == MyArray[0] && line.Split(',')[1] == MyArray[1] select line;

附带说明,在您当前的 LINQ 表达式中,您最终会拆分字符串两次。您可以通过使用let 子句来稍微提高效率:

IEnumerable<string> lines = 
    from line in csvFile 
    let parts = line.Split(new[] { ',' }, 3)
    where parts[0] == MyArray[0] && parts[1] == MyArray[1] 
    select line;

【讨论】:

  • 谢谢,我将研究“让”,因为我不熟悉它。 'let parts = line.Split(new[] { ',' }, 3)' 中的 3 引用是什么?
  • @xnguyeng 这会导致Split 在找到第二个逗号后寻找更多逗号。例如"1,2,3,4,5".Split(new[] { ',' }, 3) 返回string[] { "1", "2", "3,4,5" }
【解决方案2】:

您正在选择作为输入的行,因此您以 List&lt;string&gt; 开头并以 IEnumerable&lt;string&gt; 结尾

你可以改变

var lines = from line in csvFile where line.Split(',')[0] == MyArray[0] && line.Split(',')[1] == MyArray[1] select line;

IEnumerable<string> lines = from line in csvFile where line.Split(',')[0] == MyArray[0] && line.Split(',')[1] == MyArray[1] select line;

但是,您可以简化整个事情,因为您在此方法中所做的唯一其他事情是创建 csvFile 变量并将其作为列表返回,您可以将整个方法更改为:

public static List<string> MatchedLines(string[] MyArray)
{
    return (from line in FileReadLinestoList(@"C:\Temp\MyFile.csv")
            where line.Split(',')[0] == MyArray[0] && line.Split(',')[1] == MyArray[1] 
            select line).ToList();
}

【讨论】:

  • 谢谢,我可能会使用您的简化。我发现这种方式可读性较差,但绝对更简单,因为它节省了几行代码。
【解决方案3】:

在您的代码中包含vars 没有任何问题,尤其是,如果您正在处理 LINQ 查询。如果您决定更改 LINQ,则可能每次都需要对类型声明进行大量更改。使用var,您可以轻松避免麻烦。在很多情况下,您不需要知道中间类型是什么。

【讨论】:

  • +1;最终类型在函数的返回类型中已经是显式的,在这种特定情况下,中间类型给您的额外价值很少,因为您没有对它们执行中间转换。
  • 有道理。我只是在调试一两年内没有看过的代码时发现,我更喜欢尽可能使用显式类型。我不反对'var',但我更喜欢在类型明确时使用它。但这在使用我刚刚开始使用的 LINQ 实现时可能不是最佳实践。
  • @xnguyeng 显式类型在您刚开始学习 C# 时非常有用,但随着您变得更加熟悉,尤其是在您使用像 Visual Studio 这样具有非常好的 IntelliSense 的 IDE 时,您会发现代码中的所有这些显式类型都容易成为噪音。还有很多时候(例如匿名类型)你必须使用var
  • @xnguyeng:这里的关键是,将 var 更改为静态类型声明是否会提高代码的可读性。在某些(简单)情况下使用 LINQ 是的,但在大多数情况下不是,因为您会看到类似 IEnumerable&lt;Tuple&lt;string, int&gt;&gt; 的内容(这不是最糟糕的例子),并且仍然想查看查询。但是,如果没有 LINQ,您可能会调用一个函数,例如 var result = ProcessThisVariable(thisVariable)。在这种情况下,如果您有 Task result = ...int result = ... 它确实会增加价值,因为您可能不需要需要查看函数定义。
猜你喜欢
  • 2020-06-23
  • 1970-01-01
  • 1970-01-01
  • 2023-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-27
相关资源
最近更新 更多