toasteroven
toasteroven

Reputation: 2790

C# - Constrain an argument to be an instance of Type

I want to create a Dictionary that maps a Type to an Action, but I want the keys to be types that come from a specific parent class. So I want to do something like:

class Container
{
    private Dictionary<Type, Action> dict;

    public void AddAction(Type t, Action a) where t : typeof(SomeParentClass)
    {
        dict[t] = a;
    }
}

Where the AddAction method only accepts values of t that are types of classes that are subclasses of some specific class. I've seen something like this done in Java with the extends keyword, but I can't figure out how to do this in C#, if it's even possible.

Edit: To clarify, I don't want the AddAction method to take an instance of SomeParentClass, but rather the Type of a class that is a subclass of SomeParentClass. Is there maybe a better way than using Types?

Edit: What I'm essentially trying to do is create a dispatching service, wherein various parts of the app can register interest in an Event type and provide an Action that is called when an event of that type is fired. So imagine something like

service.RegisterInterest(typeof(MyEvent), myAction)

Where myAction is of type Action<MyEvent> (something I didn't put in the original post but should have instead of a plain Action).

Then some other part of the app can do

service.TriggerEvent(typeof(MyEvent))

Which causes all Action<MyEvent> instances registered as above to be called...So in fact that Dictionary maps a Type to a List<Action<Event>>, not a single Action.

Upvotes: 1

Views: 141

Answers (4)

Volodymyr Dombrovskyi
Volodymyr Dombrovskyi

Reputation: 269

Add assertion to the method.

Debug.Assert(t.IsAssignableFrom(typeof(SomeParentClass)));

Upvotes: 0

Lee
Lee

Reputation: 144126

If you require compile-time checking you can use generics:

public void AddAction<T>(Action a) where T : SomeParentClass
{
    dict[typeof(T)] = a;
}

You may also want to keep the non-generic version

public void AddAction(Type t, Action a)
{
    if(! typeof(SomeClass).IsAssignableFrom(t)) throw new ArgumentException();
    dict[t] = a;
}

Upvotes: 6

spender
spender

Reputation: 120400

I'd go with something like this:

class Container
{
    private Dictionary<Type, Action> dict;

    public bool AddAction(Type t, Action a) 
    {
        if (typeof(SomeParentClass).IsAssignableFrom(t))
        { 
            dict[t] = a;
            return true;
        }
        return false;
    }
}

Upvotes: 2

Michiel van Vaardegem
Michiel van Vaardegem

Reputation: 2035

Instead of Type t, use SomeParentClass t as param

Upvotes: 0

Related Questions