【问题标题】:How do I convert IEnumerable to a custom type in C#?如何在 C# 中将 IEnumerable 转换为自定义类型?
【发布时间】:2009-07-13 20:46:18
【问题描述】:

我正在使用扩展方法 OrderBy 和 ThenBy 对多个字段的自定义集合进行排序。这种排序不会影响集合,而是返回和 IEnumberable。我无法将 IEnumerable 结果转换为我的自定义集合。无论如何要更改我的集合的顺序或将 IEnumerable 结果转换为我的自定义集合?

【问题讨论】:

    标签: c# extension-methods ienumerable casting


    【解决方案1】:

    如果你的集合类型实现了IList<T>(能够Add())你可以写一个扩展方法:

    public static Extensions
    {
        public static TColl ToTypedCollection<TColl, T>(this IEnumerable ien)
            where TColl : IList<T>, new()
        {
            TColl collection = new TColl();
    
            foreach (var item in ien)
            {
                collection.Add((T) item);
            }
    
            return collection;
        }
    }
    

    【讨论】:

    • 这个想法完全帮助了我。谢谢!
    • 很有趣,我有同样的问题,想出了同样的答案,我还在四处寻找,看看是否有更好的方法来做到这一点......
    【解决方案2】:

    不,没有。当您使用查询运算符时,它不会使用原始集合的实例来生成枚举。相反,它使用私有实现(可能是匿名的,也可能不是)来提供此功能。

    如果你想在你的原始集合中使用它,你应该有一个类型的构造函数,它接受一个IEnumerable&lt;T&gt;(或者你的集合存储的任何东西,如果它是特定的),然后将查询传递给构造函数。

    然后,您可以使用它为 IEnumerable&lt;T&gt; 创建一个名为 To&lt;YourCollectionType&gt; 的扩展方法,该方法将采用 IEnumerable&lt;T&gt;,然后将其传递给您类型的构造函数并返回它。

    【讨论】:

    • 或演员,似乎更适合这种情况。
    【解决方案3】:

    没有。您可以遵循 ToList 和 ToDictionary 扩展方法建立的模式 - 编写一个类似的扩展方法来从 IEnumerable 加载您自己的集合类型。

    【讨论】:

      【解决方案4】:

      您可以编写自己的 IComparer 实例来对您的自定义集合进行排序。

      您可以蛮力循环遍历 IEnumerable 并将每个项目转储回自定义集合的新实例。

      【讨论】:

        【解决方案5】:

        您可以使用 IEnumerable 初始化列表:

        如果 items 是 IEnumerable 类型,您可以像这样创建一个列表:

        var list = new List<string>(items);
        

        或者您可以简单地调用 items.ToList()

        var list = items.ToList();
        

        【讨论】:

          【解决方案6】:

          您的自定义集合实现了哪些接口?

          如果它是 IList,那么您可以在 IEnumerable 上执行 .ToList() 如果它是一个 IDictionary,那么您可以在 IEnumerable 上执行 .ToDictionary() 等等。

          把它带到更适合你的东西上。

          如果没有相似之处,您可以为 .ToMyCollection() 编写 IEnumerable 的扩展方法。

          【讨论】:

            【解决方案7】:

            枚举和集合是完全不同的野兽。

            枚举只允许枚举,而集合具有基于索引的访问器、计数属性等。要创建一个集合,您实际上必须枚举 IEnumerable。像 List 这样的典型集合将有一个接受 IEnumerable 的构造函数。尽管如此,仍将执行枚举。

            【讨论】:

              【解决方案8】:

              如果您查看 System.Linq.Enumerable 类,有一些扩展方法可以让您将 IEnumerable 类型转换为 Array、ToList

              var myEnumerable = this.GetEnumerator();
              
              var array = myEnumerable.ToArray();
              var list myEnumerable.ToList();
              

              您可以遵循这种方法并创建一个自定义扩展方法,该方法将转换为您的自定义集合

              public static CustomCollection<TSource> ToCustomCollection<TSource>(this IEnumerable<TSource> source);
              

              【讨论】:

                【解决方案9】:

                LINQ 很酷,因为它将这样的源集合视为不可变的——它不会修改它们。使用扩展方法只需按照您指定的替代顺序枚举它们 - 您不会以这种方式构建新的自定义列表。

                我建议两个选项:

                1. 根据 LINQ-ing 的结果自己建立一个新列表
                2. 在您的自定义集合中实现排序功能(或使用一个很好的可排序通用集合作为基础),以便它可以就地排序。

                【讨论】:

                  【解决方案10】:

                  您真的需要自定义集合类型吗?听起来你想要做的一切都是由现有的泛型集合类型提供的,也许你只需要添加一个扩展方法或为它们添加一个。

                  【讨论】:

                    猜你喜欢
                    • 2012-02-08
                    • 1970-01-01
                    • 2011-02-23
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-05-17
                    • 2022-01-22
                    • 2017-01-11
                    相关资源
                    最近更新 更多