如何选择相同的列表,但具有额外的变量集

本文关键字:变量 列表 选择 何选择 | 更新日期: 2023-09-27 18:18:05

>我有一个List<MyObject>

MyObject如下。

public class MyObject
{
   public bool available;
   public bool online;
}

现在,当我从另一个函数检索此List<MyObject>时,仅设置了available字段。现在我想设置每个MyObjectonline字段。

我目前所做的是

List<MyObject> objectList = getMyObjectList();
objectList.ForEach(x => x.online = IsOnline(x));

现在设置了 online 属性,我想使用 Where 再次筛选以选择既可用又联机MyObject

objectList.Where(x => x.available && x.online);

虽然我知道上面的代码是有效且可读的,但我很好奇是否有一种 LINQ 方法来选择相同的对象,但初始化了一个变量,以便我可以将所有三行合并为一行。不幸的是,ForEach没有返回列表。

类似的东西

getMyObjectList().BetterForEach(x => x.online = IsOnline(x)).Where(x => x.available && x.online);

BetterForEach将返回x,其中包含先前设置的值以及设置的online字段。

有什么方法可以使用 LINQ 实现此目的吗?

更新
我已经删除了MyObject的其他字段。MyObject不仅包含这些字段,还包含更多字段。我宁愿不创建MyObject的新实例。

如何选择相同的列表,但具有额外的变量集

最简单的解决方案可能是创建一个类似于ForEach但返回链接列表的扩展方法:

public static List<T> ForEachThen<T>(this List<T> source, Action<T> action)
{
    source.ForEach(action);
    return source;
}

Linq 用于查询数据,而不是用于更新数据。因此,您拥有的任何选项都不会太漂亮,但仍有一些选择。

你可以这样做:

var result = 
    objectList.Select(x => 
    {
        x.online = IsOnline(x);
        return x;
    });

但是,这是非常糟糕的做法。这样会更好:

var result = 
    objectList.Select(x => new MyObject
    {
        available = x.available,
        online = IsOnline(x)
    });

但这会创建一个新对象的集合,与原始对象集无关。


这种代码通常表明您的基本设计可能存在问题。就个人而言,我会选择这样的东西(如果你可以设置一个静态方法来做IsOnline的工作(:

public class MyObject
{
   public bool Available;
   public bool Online { get { return MyObjectHelper.IsOnline(this); } }
}
...
var result = objectList.Where(x => x.Available && x.Online);

或者,如果您无法设置静态方法,也许此字段根本不需要在类MyObject

public class MyObject
{
   public bool Available;
}
...
var result = objectList.Where(x => x.Available && IsOnline(x));
var selected = getMyObjectList()
    .Select(x => new MyObject{available=x.available, online = IsOnline(x))
    .Where(x => x.available && x.online);

假设您需要在结果列表中在线访问。

您还可以向MyObject添加一个方法,例如:

public MyObject SetOnline(bool isOnline) {
   this.online = isOnline;
   return this;
}

然后做:

var selected = getMyObjectList()
    .Select(x => x.SetOnline( IsOnline(x) ))
    .Where(x => x.available && x.online);