I find that I write code like this pretty often:
public void some_callback(object sender, SomeArgs args)
{
if (sender is ObjectA)
{
var objA = sender as ObjectA;
//do something
}
else if (sender is ObjectB)
{
var objB = sender as ObjectB;
//do something else
}
}
Or similarly:
public void some_callback(object sender, SomeArgs args)
{
var objA = sender as ObjectA;
if (objA != null)
{
//do something
}
var objB = sender as ObjectB;
if (objB != null)
{
//do something else
}
}
What I would like to know is if there is a shortcut way to handle this in C#? Something along the lines of:
public void some_callback(object sender, SomeArgs args)
{
with (var obj = sender as ObjectA)
{
//do something
}
else with (var obj = sender as ObjectB)
{
//do something else
}
}
What you are asking is essentially the pattern matching that will be added in C# 7.0. See the notes. You will be able to write:
if (expr is Type v) { // code using v }
But that's for the next version.
We needed this in our code too, so with the help of SO I created a TypeSwitch object:
public sealed class TypeSwitch<T>
{
private readonly Dictionary<Type, Action<T>> _dict;
public TypeSwitch()
{
_dict = new Dictionary<Type, Action<T>>();
}
public TypeSwitch<T> Add<TChild>(Action<TChild> action) where TChild : T
{
_dict.Add(typeof (TChild), o => action((TChild) o));
return this;
}
public void Execute(T item)
{
var type = item.GetType();
foreach (var kvp in _dict)
{
if (type == kvp.Key || kvp.Key.IsAssignableFrom(type))
{
kvp.Value(item);
return;
}
}
throw new KeyNotFoundException($"{type} or its baseclass not located in typeswitch.");
}
}
which you can use like:
var obj = new BaseClass();
new TypeSwitch<BaseClass>()
.Add<Derived1>(d1 => { /*strongly typed d1 action */ })
.Add<Derived2>(d2 => { /*strongly typed d2 action */ })
.Execute(obj);
It's been pretty handy for us. Worth noting that it's not set up as-is for any asynchronous operations, but could be modified to be pretty easily.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With