【问题标题】:C# - Linq cast generic list to custom classC# - Linq 将通用列表转换为自定义类
【发布时间】:2017-11-30 10:38:21
【问题描述】:

我已经声明了一个这样的自定义集合类:

public class WipCommesse
{        
    private string FNumCommessa;
    private int FIdTipologia, FTotQtaLetta;

    public int IdTipologia
    {
        get { return FIdTipologia; }
        set { FIdTipologia = value; }
    }

    public string NumCommessa
    {
        get { return FNumCommessa; }
        set { FNumCommessa = value; }
    }

    public int TotQtaLetta
    {
        get { return FTotQtaLetta; }
        set { FTotQtaLetta = value; }
    }

}

public class WipCommesseList : List<WipCommesse>
{

}

在我的代码中,我使用 Linq 对另一个列表进行分组,并且我想转换为我的自定义类型

   WipCommesseList wipGrouped = 
   (WipCommesseList)myList.GroupBy(x => new
                            {
                                x.IdTipologia,
                                x.NumCommessa
                            }).
                            Select(g => new WipCommesse()
                            {
                                IdTipologia = g.Key.IdTipologia,
                                NumCommessa = g.Key.NumCommessa,
                                TotQtaLetta = g.Sum(i => i.QtaLanciabile)
                            }).ToList();

类的定义是相同的,但是当我调用 ToList() 方法时,它返回为 System.Collection.Generic.List 并且强制转换失败。

如何正确转换为我的班级?

【问题讨论】:

    标签: c# list linq casting


    【解决方案1】:

    代码修改如下:

     WipCommesseList wipGrouped = 
       new WipCommesseList(myList.GroupBy(x => new
                                {
                                    x.IdTipologia,
                                    x.NumCommessa
                                }).
                                Select(g => new WipCommesse()
                                {
                                    IdTipologia = g.Key.IdTipologia,
                                    NumCommessa = g.Key.NumCommessa,
                                    TotQtaLetta = g.Sum(i => i.QtaLanciabile)
                                }));
    

    这假设您在 WipCommesseList 中有以下构造函数:

    public class WipCommesseList : List<WipCommesse>
    {
        public WipCommesseList() : base()
        {
    
        }
    
        public WipCommesseList(int capacity) : base(capacity)
        {
    
        }
    
        public WipCommesseList(IEnumerable<WipCommesse> collection) : base(collection)
        {
    
        }
    }
    

    这允许您通过创建新的 WipCommesseList 对象将任何基于 WipCommesse 的可枚举类型转换为 WipCommeseList。

    【讨论】:

      【解决方案2】:
      …
      Select(g => new WipCommesse()
        {
                IdTipologia = g.Key.IdTipologia,
                NumCommessa = g.Key.NumCommessa,
                TotQtaLetta = g.Sum(i => i.QtaLanciabile)
        }).ToList();
      

      结果将是List&lt;WipCommesse&gt;

      但您正在投射到 WipCommesseList。而WipCommesseListList&lt;WipCommesse&gt;,反之则不然。当运行时类型是基类时,您不能向下转换,因为对象不是派生类型。

      您可以向WipCommesseList 添加一个显式转换运算符,该运算符采用List&lt;WipCommesse&gt; 来允许转换:您将负责创建WipCommesseList 实例。

      【讨论】:

        【解决方案3】:

        您不能将List&lt;WipCommesse&gt; 的实例转换为WipCommesseList。派生类可以有更多的方法/属性,如果你有一个WipCommesseListList&lt;WipCommesse&gt; 的实例,则只能在另一个方向上进行转换。

        您有两种解决方案:

        1. 如果 WipCommesseList 类与您在问题中定义的一样,那么它不会做太多事情,您可以只使用 List&lt;WipCommesse&gt;,也许在您的文件中使用 using WipCommesseList = List&lt;WipCommesse&gt; 别名它

        2. 如果WipCommesseList 更复杂,您可以创建一个与ToList 功能相似的扩展方法

        代码:

        public static class WipCommesseListExtensions 
        {
            public static WipCommesseList ToWipCommesseList(this IEnumerable<WipCommesse> source) 
            {
                var list = new WipCommesseList();
                foreach (var item in source)
                {
                    list.Add(item);
                }
            }
        }
        

        【讨论】:

        • 第三个选项是添加构造函数,以便可以从 WipCommesseList 的 IEnumerable 创建新对象,这就是 List 在其构造函数列表中的内容。 (见下文)
        • @netniV 是的,这也是一个不错的选择,虽然扩展方法感觉更像 LINQ,这就是我喜欢这种方法的原因
        猜你喜欢
        • 2013-05-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-27
        • 1970-01-01
        相关资源
        最近更新 更多