首页 文章

测试对象实现字典中的接口

提问于
浏览
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等)将仅从类型 Plugin 派生 .

传入的对象可以通过几代继承继承我们尝试匹配的类型之一(即IAccountsPlugin) . 这就是为什么我不能做 pluginOnDisk.GetType() .

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

2 回答

  • 2
    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.");
    }
    
  • 1

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

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

    Example:

    IAccountsPlugin plugin = ...
    Plugin locatedPlugin = FindDbPlugin(plugin);
    

相关问题