LINQ expression to optimize syntax?
foreach (var item in mainCanvas.Children)
{
if (item is Button)
{
(item as Button).Content = "this is a button";
}
}
Can I use LINQ or other 开发者_JS百科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
- The biggest improvement can be gained by using a simple
for
loop instead offoreach
. - It is also possible to improve performance slightly by casting only once.
- Using
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.
One line should do it
mainCanvas.Children.OfType<Button>.ToList().ForEach(b => b.Content = "this is a button");
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();
To only iterate over actual buttons in a collection, you can do:
foreach(Button button in mainCanvas.Children)
button.Content = "this is a button";
As far as I understand, this is syntax sugar that gets converted into Method 4 above. But don't quote me on that. (EDIT: Method 3 I meant)
精彩评论