简体   繁体   English

具有接口类型的键的字典,获取实现接口的键

[英]Dictionary with a key of interface type, get keys where interface is implemented

I have a dictionary of interface types and Func . 我有interface类型和Func的字典。 ( IBase is the base of IA , IB and IC ) IBaseIAIBIC

var _dictionary =
    new Dictionary<Type, Func<IBase, IEnumerable<IResult>>>
    {
        {typeof(IA), p => _mapper.Map(p as IA)},
        {typeof(IB), p => _mapper.Map(p as IB)},
        {typeof(IC), p => _mapper.Map(p as IC)}
    };

Passing a concrete instance of IA (or IB etc) into a method, how do I get the Func corresponding to the matching interface the instance implements: IA (或IB等)的具体实例传递给方法,如何获得与实例实现的匹配接口相对应的Func

public IEnumerable<IResult> Resolve(IBase theInstance)
{
    // This fails because theInstance.GetType() result, is not the interface type
    if (!_dictionary.TryGetValue(theInstance.GetType(), out var func)) return Enumerable.Empty<IResult>();

    var result = func.Invoke(theInstance);

    return result;
}

I'm trying to avoid using a switch statement of each of the interface types. 我试图避免使用每种接口类型的switch语句。

Type exposes a GetInterfaces() Method which returns all interfaces implemented by the Type. Type公开一个GetInterfaces()方法,该方法返回Type实现的所有接口。

If your types only implement one interface this may work, but if more are implemented you may need to rework the solution. 如果您的类型仅实现一个接口,则可能会起作用,但是如果实现了更多的接口,则可能需要重新编写解决方案。 Perhaps a factory which will return a mapper for the specified Interface type? 也许工厂将为指定的接口类型返回一个映射器?

Related reading: https://docs.microsoft.com/en-us/dotnet/api/system.type.getinterfaces?view=netframework-4.7.2 相关阅读内容: https : //docs.microsoft.com/zh-cn/dotnet/api/system.type.getinterfaces?view=netframework-4.7.2

This won't work because the dictionary type does not match the instance type. 这将不起作用,因为字典类型与实例类型不匹配。

If you inspect your dictionary, you will find that the type being stored as a key is that of the interface: 如果检查字典,您会发现存储为键的类型是接口的类型:

{Name = "IA" FullName = "SomeNameSpace.IA"}

So when you try to get the value using the type of the instance , there is no match and it fails. 因此,当您尝试使用实例的类型获取值时,没有匹配项,并且失败。

If you wanted this to work, you would need to register the type of the instance in your dictionary for proper resolution: 如果您希望此方法有效,则需要在字典中注册实例的类型以进行适当的解析:

var _dictionary = new Dictionary<Type, Func<IBase, IEnumerable<IResult>>>
{
    {typeof(IA), p => _mapper.Map(p as IA)},
    {typeof(IB), p => _mapper.Map(p as IB)},
    {typeof(IC), p => _mapper.Map(p as IC)},
    //This would make it work
    {typeof(SomeInstanceType), p=> _mapper.Map(p as IA) }
};

This is obviously not very practical. 这显然不是很实用。

What you can do instead, is try to figure out if the type implements one of the interfaces your dictionary accounts for: 相反,您可以尝试找出类型是否实现您的词典所说明的接口之一:

var interfaces = theInstance.GetType().GetInterfaces();
var key = _dictionary.Keys.Where(k => interfaces.Contains(k)).FirstOrDefault();

if (key == null) 
    return Enumerable.Empty<IResult>();

var map= _dictionary[key];
var result = map(theInstance);
return result;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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