Seeing as C# can\'t switch
on a Type (which I gather wasn\'t added as a special case because is
relationships mean that more than one distinct
With JaredPar's answer in the back of my head, I wrote a variant of his TypeSwitch
class that uses type inference for a nicer syntax:
class A { string Name { get; } }
class B : A { string LongName { get; } }
class C : A { string FullName { get; } }
class X { public string ToString(IFormatProvider provider); }
class Y { public string GetIdentifier(); }
public string GetName(object value)
{
string name = null;
TypeSwitch.On(value)
.Case((C x) => name = x.FullName)
.Case((B x) => name = x.LongName)
.Case((A x) => name = x.Name)
.Case((X x) => name = x.ToString(CultureInfo.CurrentCulture))
.Case((Y x) => name = x.GetIdentifier())
.Default((x) => name = x.ToString());
return name;
}
Note that the order of the Case()
methods is important.
Get the full and commented code for my TypeSwitch class. This is a working abbreviated version:
public static class TypeSwitch
{
public static Switch On(TSource value)
{
return new Switch(value);
}
public sealed class Switch
{
private readonly TSource value;
private bool handled = false;
internal Switch(TSource value)
{
this.value = value;
}
public Switch Case(Action action)
where TTarget : TSource
{
if (!this.handled && this.value is TTarget)
{
action((TTarget) this.value);
this.handled = true;
}
return this;
}
public void Default(Action action)
{
if (!this.handled)
action(this.value);
}
}
}