Is there a way to skip or continue in Switch expression or does every branch need to return something?

Viewed 213

I'd like to add to a list only when the switch expression finds something like so:

List<drivedType> derivedObjects = new()

derivedObjects.Add(baseObject switch
{
    derivedType d when d.field != 1 => d,
    _ => // Here I would put somthing like "continue" but it's not accepted
});

Anything of the like possible?

3 Answers

It's not clear what this code is trying to do. It may be a snippet from code that tries to filter a list of objects by type. It may be an attempt to insert a single object based on type. Or something completely different.

If the intention is to filter a list of objects by type, LINQ can be used to filter and create the final list:

var derivedObjects= baseObjects.OfType<DerivedObject>()
                               .Where(d=>d.Field !=1)
                               .ToList();

If the intention is to insert a single object :

if(baseObject is DerivedType d && d.Field !=1)
{
    derivedObjects.Add(d);
}

Here I would put somthing like continue

No continue, the switch expression is an expression, it has to return something.

The only exception in C# is that these expressions (switch expressions, conditional expressions, etc) are allowed to throw instead, much like a function is allowed to throw instead of return a value. So you could do something like this, and indeed it's a very common pattern:

derivedObjects.Add(baseObject switch
{
    derivedType d when d.field != 1 => r,
    _ => throw new InvalidOperationException()
});

Edit: Just in case you don't know, there is actually an easier way to write your code, without that when:

derivedObjects.Add(baseObject switch
{
    derivedType { field: not 1 } d => r,
    _ => throw new InvalidOperationException()
});

This is better done with a switch statement instead of a switch expression

List<drivedType> derivedObjects = new()

switch(baseObject)
{
    case derivedType d when d.field != 1:
        derivedObjects.Add(d);
        break;
    default:
        break;
}

I.e., when the value is as desired, add it, otherwise do not. But since you have only one valid case, an if statement seems more appropriate than a switch statement. You must use the is keyword to introduce a pattern when not inside a case label: baseObject is pattern_expression

In C# 9.0 you can also use the new relational and disjunctive patterns

case derivedType { field: < 1 or > 1 } d:
Related