Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio C# shortcut for cast followed by check for null

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
    }
}
like image 790
jwatts1980 Avatar asked Nov 23 '25 10:11

jwatts1980


2 Answers

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.

like image 131
krontogiannis Avatar answered Nov 26 '25 01:11

krontogiannis


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.

like image 23
Jonesopolis Avatar answered Nov 26 '25 01:11

Jonesopolis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!