Seeing as C# can't switch on a Type (which I gather wasn't added as a special case because is-a relationships mean that more than one distinct case might apply), is there a better way to simulate switching on type than this?
void Foo(object o)
{
if (o is A)
{
((A)o).Hop();
}
else if (o is B)
{
((B)o).Skip();
}
else
{
throw new ArgumentException("Unexpected type: " + o.GetType());
}
}
I would either
Create an interface IFooable, then make your A and B classes to implement a common method, which in turn calls the corresponding method you want:
Note, that it's better to use "as" instead first checking with "is" and then casting, as that way you make 2 casts (expensive).
You're looking for
Discriminated Unions
which are a language feature of F#, but you can achieve a similar effect by using a library I made, called OneOfhttps://github.com/mcintyre321/OneOf
The major advantage over
switch
(andif
andexceptions as control flow
) is that it is compile-time safe - there is no default handler or fall throughIf you add a third item to o, you'll get a compiler error as you have to add a handler Func inside the switch call.
You can also do a
.Match
which returns a value, rather than executes a statement:I agree with Jon about having a hash of actions to class name. If you keep your pattern, you might want to consider using the "as" construct instead:
The difference is that when you use the patter if (foo is Bar) { ((Bar)foo).Action(); } you're doing the type casting twice. Now maybe the compiler will optimize and only do that work once - but I wouldn't count on it.
Yes - just use the slightly weirdly named "pattern matching" from C#7 upwards to match on class or structure:
I liked Virtlink's use of implicit typing to make the switch much more readable, but I didn't like that an early-out isn't possible, and that we're doing allocations. Let's turn up the perf a little.
Well, that makes my fingers hurt. Let's do it in T4:
Adjusting Virtlink's example a little:
Readable and fast. Now, as everybody keeps pointing out in their answers, and given the nature of this question, order is important in the type matching. Therefore: