简体   繁体   中英

How can I use 'continue' and `break` in an extension method?

I have defined the following extension method:

public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
{
   foreach (T obj in sequence)
   { 
      action(obj); 
   } 
}

I can then use it as:

new [] {1, 2, 3} // an IEnumerable<T>
.ForEach(n => 
{
  // do something 
});

I want to be able to take advantage of continue and break inside my extension method so that I can do:

new [] {1, 2, 3}
.ForEach(n => 
{
    // this is an overly simplified example
    // the n==1 can be any conditional statement
    // I know in this case I could have just used .Where
    if(n == 1) { continue; }
    if(n == -1) { break; }      
    // do something 
});

Can these keywords only be used within a for , foreach , while or do-while loops?

Can these keywords only be used within a for, foreach, while loops?

Yes. Those statements are limited to loop types. As the docs say :

The continue statement passes control to the next iteration of the enclosing while, do, for, or foreach statement in which it appears.

And :

The break statement terminates the closest enclosing loop or switch statement in which it appears. Control is passed to the statement that follows the terminated statement, if any.

I'd recommend you use a regular foreach , which is self expressive as is. I think any attempt to use them semantically inside your ForEach extension method will result in weirder code than using a regular loop.

I mean, is this not simpler?:

var arr = new [] {1, 2, 3}
foreach (int number in arr)
{
    if(n == 1) { continue; }      
    if(n == -1) { break; }      
}

In addition to Yuval's answer I'd like to add that you could implement something like this as follows:

Change the Action<T> into a Func<T, bool> which takes a T parameter and returns a bool result.

The "continue" case could easily be handled by returning from the function upon the condition, thus continuing with the next iteration of the loop.

The "break" case could be handled by returning a bool from the function that indicates whether to continue or not:

public static void ForEach<T>(this IEnumerable<T> sequence, Func<T, bool> action)
{
  foreach (T obj in sequence)
  { 
    if (!action(obj)) 
      break;
  }
}

new [] {1, 2, 3}.ForEach(n => 
{
    if(n == 1) { return true;}      
    if(n == -1) { return false; }  

    // do something 
    ...
    return true;
});

Yes, those keyword are limited to while , do , for , and foreach (as Yuval referenced).

This code would resemble roughly the same as you ask:

bool shouldBreak = false;

new [] {1, 2, 3}
.ForEach(n => 
{
    if (!shouldBreak)
    {
        if(n == 1) { /* no action */ }      
        else if(n == -1) { shouldBreak = true; }
        else
        {
            // do something 
        }
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM