【问题标题】:C# Converting List<int> to List<double>C# 将 List<int> 转换为 List<double>
【发布时间】:2010-01-18 07:32:21
【问题描述】:

我有一个List&lt;int&gt;,我想将它转换为List&lt;double&gt;。除了像这样循环List&lt;int&gt; 并添加到新的List&lt;double&gt; 之外,还有什么方法可以做到这一点:

List<int> lstInt = new List<int>(new int[] {1,2,3});
List<double> lstDouble = new List<double>(lstInt.Count);//Either Count or Length, I don't remember

for (int i = 0; i < lstInt.Count; i++)
{
    lstDouble.Add(Convert.ToDouble(lstInt[0]));
}

有什么奇特的方法可以做到这一点吗?我使用的是 C# 4.0,所以答案可能会利用新的语言功能。

【问题讨论】:

  • (作为记录,请注意 C# 4.0 变体不适用于具体类型 (List&lt;T&gt;),通常不适用于列表 (IList&lt;T&gt;),并且不会在intdouble 之间工作)

标签: c# generics


【解决方案1】:

可以按照其他人的建议使用Select,但您也可以使用ConvertAll

List<double> doubleList = intList.ConvertAll(x => (double)x);

这有两个好处:

  • 它不需要 LINQ,因此如果您使用 .NET 2.0 并且不想使用 LINQBridge,您仍然可以使用它。
  • 更高效:ToList 方法不知道Select 的结果大小,因此它可能需要随时重新分配缓冲区。 ConvertAll 知道源和目标大小,因此它可以一口气完成所有操作。它也可以在没有迭代器抽象的情况下这样做。

缺点:

  • 它只适用于List&lt;T&gt; 和数组。如果你得到一个普通的IEnumerable&lt;T&gt;,你将不得不使用SelectToList
  • 如果您在项目中大量使用 LINQ,那么在此处继续使用它可能会更加一致。

【讨论】:

  • 在 .NET 3.5 中也可用
  • ConvertAll 不只是 LINQ 表达式的包装器吗?
  • 除了更清楚地表明你的意图之外,Select 有什么不同吗?
  • @Filip, @VVS:见“优势”中的第二点。想象一个包含一百万个条目的列表 - ConvertAll 可以创建一个包含一百万个条目的新列表,但 Select(...).ToList(...) 不能 - 它必须保留一个可调整大小的缓冲区。
  • @Marc:确实。发帖人提到了 .NET 4.0,所以我有点假设他对 .NET 2.0 不感兴趣。
【解决方案2】:

您可以使用 LINQ 方法:

List<double> doubles = integers.Select<int, double>(i => i).ToList();

或:

List<double> doubles = integers.Select(i => (double)i).ToList();

另外,列表类有一个 ForEach 方法:

List<double> doubles = new List<double>(integers.Count);
integers.ForEach(i => doubles.Add(i));

【讨论】:

  • 这需要是 Select(i => i).ToList();有没有办法将 语法与“类型”变量而不是 int 一起使用?
  • @Chris:实际上通常只是 integers.Select(i =&gt; (double)i) 是惯用的。但是不,泛型是编译时特性——如果你想使用只在执行时知道的类型,你需要使用反射。 C# 4 中的动态类型可能会帮助您解决这个问题,但您必须先给出一个更具体的示例,然后才能确定。
  • 使用第二个演示,我可以创建一个 double 类型的反射列表,然后使用 foreach 东西从基于 int 的列表中添加项目。升职会发生,一切快乐的事情都会发生。这个回答实际上解决了我的问题,但上面的回答更简洁地表达了我提出的问题。
【解决方案3】:

您可以使用方法组:

lstDouble = lstInt.Select(Convert.ToDouble)

【讨论】:

    【解决方案4】:

    您可以使用Select 扩展方法来做到这一点:

    List<double> doubleList = intList.Select(x => (double)x).ToList();
    

    【讨论】:

    • 那么不只是使用循环有什么意义吗?性能明智?
    • @Chris:使用 Select 和 ToList 不会更有效率。 ConvertAll 可能 - 你失去了在 Add 中检查的开销,但是有多次调用委托的开销。你有证据表明这段代码对你来说是一个瓶颈吗?
    • 完全没有证据。在我的应用程序中,“双重”示例将是动态的,因此如果没有反射,很难进行投射。我只是想知道是否有一些简洁的 Lamba 函数或我不知道的东西可以这么说来处理铸造。
    • @Chris:很可能,您可以构建一个表达式树来执行转换。但是,此时您有一个稍微不同的问题。
    • 我只能使用反射。我的问题已经解决了。我结束了只做一个 foreach 并添加到 的动态反射生成列表中。感谢您的帮助。
    【解决方案5】:

    您可以在 .Net Framework 2.0 中使用 ConvertAll 方法,这里是一个示例

            List<int> lstInt = new List<int>(new int[] { 1, 2, 3 });
            List<double> lstDouble = lstInt.ConvertAll<double>(delegate(int p)
            {
                return (double)p;
            });
    

    【讨论】:

      【解决方案6】:

      您可以使用 Select 或 ConvertAll。请记住,ConvertAll 在 .Net 2.0 中也可用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多