开发者

LINQ expression to optimize syntax?

开发者 https://www.devze.com 2023-01-18 01:27 出处:网络
foreach (var item in mainCanvas.Children) { if (item is Button) { (item as Button).Content = \"this is a button\";
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 of foreach.
  • 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)

0

精彩评论

暂无评论...
验证码 换一张
取 消