转换 Linq 结果无法按预期工作

本文关键字:工作 Linq 结果 转换 | 更新日期: 2023-09-27 18:36:55

这可能是一个愚蠢的问题,因为我对Linq很陌生。我创建了一个返回字符串列表的 Linq 表达式。我可以迭代结果。但是,当我将结果转换为列表时,它会产生运行时错误。请参阅此代码:

class Product { public string name; }
class Program
{
    static void Main(string[] args)
    {
        Dictionary<string, Product> p1 = new Dictionary<string, Product>();
        p1["a"] = new Product() { name = "first"} ;
        p1["b"] = new Product() { name = "second" };
        var Y = p1.Values.Select(x => x.name);
        foreach (string s in Y) { Console.WriteLine(s); }
        List<string> ls = (List<string>)p1.Values.Select(x => x.name); // this fails !?
        Console.Read();
    }
}

转换 Linq 结果无法按预期工作

它失败,因为Select不返回列表。 您需要使用ToList来具体化您的查询:

 List<string> ls = p1.Values.Select(x => x.name).ToList();

LINQ方法使用延迟执行,这意味着在您通过迭代(例如使用 foreach)或使用某些方法强制迭代(如 ToArrayToList 方法)运行查询之前,它们不会返回结果。

以下是一些有用的读物:

  • 惰性求值
  • LINQ 和延迟执行
  • LINQ to XML 中的延迟执行和延迟计算
p1.Values.Select(x => x.name); // this fails !?

是的,它确实如此,因为Select不会返回隐藏在IEnumerable<T>接口后面的List<string>。 使用 ToList()

var ls = p1.Values.Select(x => x.name).ToList();
List<string> ls = p1.Values.Select(x => x.name).ToList();

通常是执行此操作的正确方法。Linq 方法(例如 Select)返回 IEnumerable,因此不能以这种方式强制转换它。IEnumerable 是一个非常通用的集合,而 List 是具体的。你不能安全地假设每个 IEnumerable 都是 List,但你可以说每个 List 也是 IEnumerable...

在 MSDN 文档中,您可以看到,如果强制转换类型实际上与目标类型不同,则此类显式强制转换将失败。请参阅此内容以更好地了解转换 http://msdn.microsoft.com/en-us/library/ms173105.aspx

或者你可以这样做:

var results = 1.Values.Select(x => x.name);
List<string> ls = new List<string>(results); 

通过使用接受 IEnumerable 的重载构造函数,但ToList()在这种情况下更为常见。

使用 .ToList() 扩展方法。那时它不是一个列表,而是一个IEnumerable<string>.

Linq在这种情况下返回一个不是List<string>IEnumerable<string>,你可以告诉Linq通过使用表达式末尾的.ToList()将其转换为字符串:

List<string> ls = p1.Values.Select(x => x.name).ToList();