运行时类型参数

时间:2013-10-08 19:39:50

标签: c# generics automapper

我正在尝试调用一个需要两个类型参数的方法,其中一个参数在运行时才会被识别。

public static TTarget Map<TSource, TTarget>(TSource source, string key) {
    var typeMapping = TypeMapper.mappings.FirstOrDefault(m => m.Key == key);
    if (typeMapping.Value == null) return null;

    Type type = Type.GetType(typeMapping.Value.ToString());
    if (type == null) return null;

    var method = typeof(Mapper).GetMethod("Map").MakeGenericMethod(typeof(TSource), type);
    return method.Invoke(source); // throws exception
}

我有两个问题:

  1. 我正在使用AutoMapper,所以Mapper.Map<TSource, TDestination>(TSource source)是我试图调用的方法,但是在调用method.invoke(source)时我得到了异常

      

    无法解析方法调用(TSource)。 候选人是:对象调用(对象,对象[])对象调用(对象,Reflection.BindingFlags,Reflection.Binder,object [],CultureInfo)

    我理解这意味着什么,但我如何调用Mapper.Map()传递TSource source而非object的参数?

  2. 如何返回TTarget而不是method.Invoke()返回的对象?

1 个答案:

答案 0 :(得分:0)

首先:我认为,我的意思是,编译器错误(在编译时发生)而不是异常(在运行时发生)。设置一个repro,我收到你在编译时引用的消息。

接下来,问题1:“如何调用Mapper.Map()”。如错误所述,您以与any of its possible signatures不匹配的方式调用MethodInfo.Invoke。你想要的重载是第一个(更简单)。

在这里,根据文档,第一个参数Invoke是调用 on 方法的对象,或者,对于静态方法(你在这里得到的那种),你喜欢什么(传递null以使我们明显调用静态方法很常见。)

Invoke第二个参数应为object数组,其中包含要传递给方法的参数。这里唯一的参数是source,但它仍然需要进入数组。

因此,您需要将通话更改为Invokemethod.Invoke(null, new object[]{source})

修复了我们遇到的问题2:“如何返回TTarget而不是object”。如果您对类型转换错误在运行时失败感到高兴,这就像转换一样简单:

return (TTarget)method.Invoke(null, new object[]{source});

我们已经完成了。