【问题标题】:Creating a list of objects from LINQ select new从 LINQ 创建对象列表 select new
【发布时间】:2018-02-27 14:55:23
【问题描述】:

为什么第一个 linq 查询有效,而第二个无效?

var locations =
    from routeLocation in db.Table<RouteLocation>()
    join location in db.Table<Location>() on routeLocation.LocationId equals location.Id
    where functionalLocation.RouteId == routeId
    select new Location() { Id = location.Id, ParentId = location.ParentId, 
                            Name = location.Name 
                          };


var locations =  
    from routeLocation in db.Table<RouteLocation>()
    join location in db.Table<Location>() on routeLocation.LocationId equals location.Id
    where functionalLocation.RouteId == routeId
    select new { Location = location };

第二个查询的编译器错误是:

不能隐式转换类型 'System.Collections.Generic.List>' 到'System.Collections.Generic.List

我尝试将 var 声明为位置列表,但仍然得到相同的错误。我是否可以使用第二个示例中的语法,而不必像第一个示例中那样指定每个属性?

【问题讨论】:

  • 错误信息一目了然!
  • 那么如何解决呢?
  • select new { ...} 而不是 select new Location { ...}

标签: c# linq generics


【解决方案1】:

第二个查询由new {...} 创建一个新的匿名类型。因此,locations 的类型是这种匿名类型的 IEnumerable,youre probably trying to cast into aList` 会产生显示的错误。

如果你想创建一个新的Location对象列表,那么你需要在Location类中创建一个复制构造函数(即一个带有签名Location(Location location)的构造函数,它复制给定@987654328的所有字段@ 进入新的。然后您可以将查询更改为以下内容:

var locations =  
    from routeLocation in db.Table<RouteLocation>()
    join location in db.Table<Location>() on routeLocation.LocationId equals location.Id
    where functionalLocation.RouteId == routeId
    select new Location(location);

这会产生一个IEnumerable&lt;Location&gt;,可以通过ToList() 方法将其转换为List&lt;Location&gt;

【讨论】:

  • 1.您不需要 需要 复制构造函数,按照第一个示例使用对象初始化器语法非常好。 2. ToList 不是给你IList,而是具体的List
  • ToList() 的返回类型是对的。我在答案中解决了这个问题。您对初始化程序语法也是正确的。但是,我不会依赖它,而是总是使用复制构造函数。否则,这会将对象的复制语义分布到代码中使用初始化器语法的所有位置。复制构造函数将它封装在一个地方。 (无论如何,我尽量避免复制引用类型的对象)
  • 我的意思是你不需要一个。您的回答暗示这是一项要求,而不是您认为的最佳做法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-07
  • 2017-06-26
相关资源
最近更新 更多