简体   繁体   English

如何传递对象类型以调用泛型方法

[英]How to pass an object type to call a generic method

My generic method is this 我的通用方法是这样

public static class AppContainerInstaller
{
    public static IMessageHandler<T> Resolve<T>() 
    {
        return _container.Resolve<IMessageHandler<T>>();
    }
}

I am trying to call this generic method from a different class 我试图从另一个类中调用此通用方法

public static string ProcessMessage(IMessage message)
{
    messageHandler = AppContainerInstaller.Resolve<message.GetType()>();
    // THe previous line throws an error.
    return messageHandler.Handle(message);
}

Can anyone tell me how to pass the type of message to a generic method? 谁能告诉我如何将消息类型传递给通用方法?

You have to do this: 您必须这样做:

messageHandler = AppContainerInstaller.Resolve<IMessage>();

Resolve method is the one who should get the type being passed in T. You see, when using generics, you must provide an actual type.And you probably want to change Resolve to get a T parameter, so you can pass message . Resolve方法是应该在T中传递类型的方法。您看到,使用泛型时,必须提供一个实际的类型。您可能想更改Resolve以获取T参数,以便传递message Something like this: 像这样:

public static IMessageHandler<T> Resolve<T>(T param) 

and you call it like this: 您这样称呼它:

messageHandler = AppContainerInstaller.Resolve<IMessage>(message);

There are two ways to get the runtime type: pass the message as a parameter or use reflection. 有两种获取运行时类型的方法:将消息作为参数传递或使用反射。

Modifying the method: 修改方法:

public static IMessageHandler<T> Resolve<T>(T unused) 
{
    return _container.Resolve<IMessageHandler<T>>();
}

Which will allow runtime type lookup: 这将允许运行时类型查找:

// Cast to dynamic to force runtime type
messageHandler = AppContainerInstaller.Resolve((dynamic) message);

You can also to use reflection although there is a performance penalty. 您也可以使用反射,尽管这会降低性能。

private static readonly MethodInfo ResolveMethodInfo
    = typeof(AppContainerInstaller).GetMethod("Resolve", BindingFlags.Public | BindingFlags.Static);

// Assuming there exists a non-generic interface IMessageHandler
private readonly ConcurrentDictionary<Type, Func<IMessageHandler>> _methodCache
    = new ConcurrentDictionary<Type, Func<IMessageHandler>>();

public static string ProcessMessage(IMessage message)
{
    messageHandler = Resolve(message.GetType());
    return messageHandler.Handle(message);
}

private IMessageHandler Resolve(Type type)
{
    // Cache the generated method to avoid repeated reflection penalty.
    var resolve = _methodCache.GetOrAdd(type, () => ResolveMethodInfo.MakeGenericMethod(type));
    return resolve();
}

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

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