使用lambda表达式调用字典的键对象的方法

时间:2012-08-22 00:28:37

标签: c# linq lambda

如果我有类似的话:

Dictionary<SomeObject, SomeOtherObject> _mydictionary 

SomeObject有一个方法:SomeMethod()

如何使用lambda表达式调用方法SomeMethod(),而无需将键转换为列表并执行ForEach。 ToList()使它过于昂贵。或者,lambda中的等价物为:

foreach(SomeObject o in _mydictionary.Keys)
  o.SomeMethod();

???

我试过了:

_mydictionary.ToList().ForEach(x => x.SomeMethod());

ToList();

似乎太贵了

2 个答案:

答案 0 :(得分:1)

没有内置的扩展方法来调用void方法的集合,无论是委托还是对象集合的成员。

但是,您可以相对轻松地创建一个:

public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
  foreach (var item in items) action(item);
}

现在你可以用LINQish方式调用所有这些方法:

_mydictionary.Keys.ForEach(x => x.SomeMethod());

您已经可以访问.Keys上的IDictionary<TKey,TValue>集合属性;您无需在任何地方拨打.ToList()


如果SomeMethod()是一个函数,并且您想创建一个结果集,那么您可以使用内置的扩展方法Select()

var results = _mydictionary.Keys.Select(x => x.SomeMethod());

正如George正确指出的那样,除非需要,否则不会调用SomeMethod() - 也就是说,除非你实际使用结果迭代它们。这可以避免创建新集合的开销,但是应该注意避免多次枚举。

答案 1 :(得分:1)

使用Reactive Extensions (Rx)

var keys = _mydictionary.Keys;
// convert the enumerable sequence of keys to an observable sequence
var observableKeys = keys.ToObservable ();
// invoke SomeMethod for each key
await observableKeys.ForEachAsync (obj =>
    obj.SomeMethod ());

此代码将在不调用在调用第一个SomeMethod之前枚举序列的调用的情况下执行,并且不会分配另一个集合。

不幸的是,we're waiting for a new release的Interactive Extensions(Ix)具有完全相同的功能,而无需从可枚举序列转换为可观察序列。