简体   繁体   中英

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 .

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;
}

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;
    }
}

代替Type t ,使用SomeParentClass t作为参数

将断言添加到方法中。

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM