IEnumerable<MyClass> objects = ...
foreach(MyClass obj in objects)
{
if(obj.someProperty != null)
SomeFunction(obj.someProperty);
}
I get the feeling I can write a smug LINQ version using a lambda but all my C# experience is 'classical' i.e more Java-like and all t开发者_如何学运维his Linq stuff confuses me.
What would it look like, and is it worth doing, or is this kind of Linq usage just seen as showing off "look I know Linq!"
LINQ itself doesn't contain anything for this - I'd would use a normal foreach
loop:
foreach (var value in objects.Select(x => x.someProperty)
.Where(y => y != null))
{
SomeFunction(value);
}
Or if you want a query expression version:
var query = from obj in objects
let value = obj.SomeProperty
where value != null
select value;
foreach (var value in query)
{
SomeFunction(value);
}
(I prefer the first version, personally.)
Note that I've performed the selection before the filtering to avoid calling the property twice unnecessarily. It's not for performance reasons so much as I didn't like the redundancy :)
While you can use ToList()
and call ForEach()
on that, I prefer to use a straight foreach
loop, as per Eric's explanation. Basically SomeFunction
must incur a side-effect to be useful, and LINQ is designed with side-effect-free functions in mind.
objects.where(i => i.someProperty != null)
.ToList()
.ForEach(i=> SomeFunction(i.someProperty))
Although it can be done with Linq, sometimes its not always necessary. Sometimes you lose readability of your code. For your particular example, I'd leave it alone.
One option is to use the pattern outlined in the book Linq In Action which uses an extension method to add a ForEach operator to IEnumerable<>
From the book:
public static void ForEach<T> (this IEnumerable<T> source, Action<T> func)
{
foreach (var item in source)
func(item)
}
Then you can use that like this:
(from foo in fooList
where foo.Name.Contains("bar")
select foo)
.ForEach(foo => Console.WriteLine(foo.Name));
LINQ is used to create a result, so if you use it to call SomeFunction
for each found item, you would be using a side effect of the code to do the main work. Things like that makes the code harder to maintain.
You can use it to filter out the non-null values, though:
foreach(MyClass obj in objects.Where(o => o.someProperty != null)) {
SomeFunction(obj.someProperty);
}
You can move the if statement into a Where clause of Linq:
IEnumerable<MyClass> objects = ...
foreach(MyClass obj in objects.Where(obj => obj.someProperty != null)
{
SomeFunction(obj.someProperty);
}
Going further, you can use List's ForEach
method:
IEnumerable<MyClass> objects = ...
objects.Where(obj => obj.someProperty != null).ToList()
.ForEach(obj => SomeFunction(obj.someProperty));
That's making the code slightly harder to read, though. Usually I stick with the typical foreach
statement versus List's ForEach
, but it's entirely up to you.
精彩评论