foreach (var item in mainCanvas.Children)
{
if (item is Button)
{
(item as Button).Content = "this is a button";
}
}
Can I use LINQ or other feature of .NET 4 to be more concise (maybe performant)?
You can use Enumerable.OfType:
foreach (var button in mainCanvas.Children.OfType<Button>())
{
button.Content = "this is a button";
}
Performance Measurements
Method 1: OPs original suggestion
foreach (var item in mainCanvas.Children)
{
if (item is Button)
{
(item as Button).Content = "this is a button";
}
}
Method 2: OfType
foreach (var button in mainCanvas.Children.OfType<Button>())
{
button.Content = "this is a button";
}
Method 3: Only cast once
foreach (var item in mainCanvas.Children)
{
Button button = item as Button;
if (button != null)
{
button.Content = "this is a button";
}
}
Method 4: for loop:
List<object> children = mainCanvas.Children;
for (int i = 0; i < children.Count; ++i)
{
object item = children[i];
if (item is Button)
{
(item as Button).Content = "this is a button";
}
}
Results
Iterations per second Method 1: 18539180 Method 2: 7376857 Method 3: 19280965 Method 4: 20739241
Conclusion
for loop instead of foreach.OfType is considerably slower.But remember to optimize readability first, and only optimize performance if you have performance profiled and found that this specific code is the performance bottleneck.
object instead of var in ... say method 3? What if something like IButton is used instead of Button when casting? Finally, how do you measure the performance? Are the numbers consistent from run to run? With JIT, pre-emption, noise is possible. Thanks.One line should do it
mainCanvas.Children.OfType<Button>.ToList().ForEach(b => b.Content = "this is a button");
foreach should operate on an IEnumerable, which can be a lazy collection.See if there is an OfType<T> extension.
foreach (var item in mainCanvas.Children.OfType<Button>())
{
item.Content = "this is a button";
}
If not, you can use:
foreach (var item in mainCanvas.Children.Where(item=>item is Button).Cast<Button>())
{
item.Content = "this is a button";
}
Not that it's particularly superior, but there is something nice about this syntax:
Using LINQ and the Microsoft ReactiveExtensions framework,
mainCanvas.Children
.OfType<Button>()
.Do(b => b.Content = "I'm a button!")
.Run();
Button castedItem = null; foreach ... castedItem = item as Button; if (castedItem != null) { // do work here } } // end foreach. That way you are cutting the use of reflection into 2, this gaining some speed-up. A LINQ query should be as performant, probably more readable.forever beats non-stupidly constructedforeachin C#.