3

我有一个List<MyObject>

MyObject如下。

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

现在,当我List<MyObject>从另一个函数中检索它时,只available设置了该字段。现在我想设置online每个MyObject.

我目前做的是

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 的新实例。

4

3 回答 3

3

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

public static List<T> ForEachThen<T>(this List<T> source, Action<T> action)
{
    source.ForEach(action);
    return source;
}
于 2013-06-13T08:25:50.413 回答
2

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));
于 2013-06-13T08:19:09.777 回答
2
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);
于 2013-06-13T08:19:32.437 回答