1

我有一本注册类型的字典。

Dictionary<Type, Type> knownTypes = new Dictionary<Type, Type>() {
   { typeof(IAccountsPlugin), typeof(DbTypeA) },
   { typeof(IShortcodePlugin), typeof(DbTypeB) }
};

我需要测试一个对象是否将特定接口实现为键,如果是,则实例化对应的值。

public Plugin FindDbPlugin(object pluginOnDisk)
{
    Type found;
    Type current = type.GetType();

    // the below doesn't work - need a routine that matches against a graph of implemented interfaces
    knownTypes.TryGetValue(current, out found); /
    if (found != null)
    {
        return (Plugin)Activator.CreateInstance(found);
    }
}

将创建的所有类型(在本例中为 DbTypeA、DbTypeB 等)只会从 type 派生Plugin

传入的对象可能是通过几代继承从我们试图匹配的一种类型(即 IAccountsPlugin)继承而来的。这就是为什么我不能这样做pluginOnDisk.GetType()

有没有办法测试一个对象是否实现了一个类型,然后创建该类型的新实例,使用字典查找而不是暴力强制和在长循环中测试 typeof?

4

2 回答 2

2

将此方法更改为通用方法,并指定您要查找的对象的类型:

public Plugin FindDbPlugin<TKey>(TKey pluginOnDisk)
{
    Type found;
    if (knownTypes.TryGetValue(typeof(TKey), out found) && found != null)
    {
        Plugin value = Activator.CreateInstance(found) as Plugin;
        if (value == null)
        {
            throw new InvalidOperationException("Type is not a Plugin.");
        }

        return value;
    }

    return null;
}

例子:

IAccountsPlugin plugin = ...
Plugin locatedPlugin = FindDbPlugin(plugin);
于 2012-09-23T22:35:06.903 回答
1
public Plugin FindDbPlugin(object pluginOnDisk) {        
    Type found = pluginOnDisk.GetType().GetInterfaces().FirstOrDefault(t => knownTypes.ContainsKey(t));
    if (found != null) {
        return (Plugin) Activator.CreateInstance(knownTypes[found]);
    }
    throw new InvalidOperationException("Type is not a Plugin.");
}
于 2012-09-23T22:53:24.327 回答