有什么方法可以用LINQ查询来预测"原始加上一些变化"吗?

Joh*_*ers 5 c# linq projection

我有代码正在构建一个对象集合.我正在努力减少.ToList()我拨打的电话数量,所以我试图IEnumerable<T>尽可能长时间地保持它.

除了需要设置为传递给调用方法的值的两个属性之外,我几乎完成了它:

private IEnumerable<X> BuildCollection(int setMe){
    IEnumerable<Y> fromService = CallService();
    IEnumerable<X> mapped = Map(fromService);
    IEnumerable<X> filteredBySomething = FilterBySomething(mapped);

    IEnumerable<X> sorted = filteredBySomething
                                .OrderBy(x=>x.Property1)
                                .ThenBy(x=>x.Property2);

    // Here's the problem: return "sorted", but with each "Property3"
    //  and "Property4" set to "setMe". I don't want to do:

    var sortedList = sorted.ToList();
    sortedList.ForEach(s=>
    {
        s.Property3 = setMe;
        s.Property4 = setMe;
    };

    return sortedList;
}
Run Code Online (Sandbox Code Playgroud)

如果可以在a中使用某种通配符select,那么我可以执行以下操作:

return from f in filteredBySomething
    order by f.Property1, f.Property2
    select new {
        f.*,
        f.Property3 = setMe,
        f.Property4 = setMe
    };
Run Code Online (Sandbox Code Playgroud)

也就是说,我想回流已排序的对象,但将Property3和Property4设置为传入的值.

有一种优雅的方式来做到这一点?

PS我不认为这很重要,但最终会将该集合作为viewmodel发送到ASP.NET视图.显然,.ToList()可能必须在View获得之前调用它,但我希望这是唯一的时间.

PPS我应该说这种类型X有大约30个属性!运用

select new {
    x.Property1,
    x.Property2,
    Property3 = setMe,
    Property4 = setme,
    // ...
}
Run Code Online (Sandbox Code Playgroud)

没有用,因为这...将是另外26个属性.

Jas*_*zun 6

而不是这个:

var sortedList = sorted.ToList();
sortedList.ForEach(s=>
{
    s.Property3 = setMe;
    s.Property4 = setMe;
};
Run Code Online (Sandbox Code Playgroud)

做这个:

sorted = sorted.Select(x =>
{
    x.Property3 = setMe;
    x.Property4 = setMe;
    return x;
});
Run Code Online (Sandbox Code Playgroud)

但是,如果您不想修改对象,则可以执行以下操作:

sorted = sorted.Select(x => new X()
{
    Property3 = setMe,
    Property4 = setMe,
    // set all other properties to what they were before
    // example: Property1 = x.Property1
});
Run Code Online (Sandbox Code Playgroud)

我不相信有比这两个更好的方法.

  • 这确实具有在`.Select`中应该是纯函数的变异状态的ick因子. (2认同)

Joh*_*ers 0

这就是我的结论:

private IEnumerable<X> BuildCollection(int setMe){
    IEnumerable<Y> fromService = CallService();
    IEnumerable<X> mapped = Map(fromService);
    IEnumerable<X> filteredBySomething = FilterBySomething(mapped);

    IEnumerable<X> sorted = filteredBySomething
                                .OrderBy(x=>x.Property1)
                                .ThenBy(x=>x.Property2);
    // The method already returns IEnumerable<X> - make it an iterator    
    foreach (var x in sorted)
    {
        x.Property3 = setMe;
        x.Property4 = setMe;
        yield return x;
    }
}
Run Code Online (Sandbox Code Playgroud)