【问题标题】:Passing type as a parameter in an api that takes a generic type [duplicate]在采用泛型类型的api中将类型作为参数传递[重复]
【发布时间】:2019-12-06 18:59:07
【问题描述】:

我可以看到很多类似的问题,但我找不到涵盖这种情况的解决方案:

我有以下代码:

Service.AddQuery(T => new ServiceFactory.New()
    .AddQueryType<Test>()
    .Register(T)
    .Create());


public class Test
{
    ...
}

这不是我的代码,不能更改。

由于系统有插件架构,我无法提前知道Test类型,所以我需要做这样的事情:

RegisterService(Type MyQueryType)
{
    Service.AddQuery(T => new ServiceFactory.New())
        .AddQueryType<MyQueryType>()
        .Register(T)
        .Create());
}

但我找不到如何使这项工作。

我尝试传递 typeof,我尝试使用 Activator.CreateInstance 等创建实例,但我找不到如何实现。

如何做到这一点?


编辑:

这被标记为可能与How do I use reflection to call a generic method? 重复,尽管我的问题的第一行说:

我可以看到很多类似的问题,但我找不到涵盖此案例的解决方案

另一个问题的答案是根据其名称调用一种方法。这里注入类型的位置位于链的中间(在 AddQuery 和 Register 之间),我看不出该答案中的方法如何工作。但我很高兴被证明是错误的。

【问题讨论】:

  • @thehennyy:我将如何使用该答案中的方法来仅替换 .AddQueryType 部分?
  • 你可能不能,使用运行时类型意味着一直使用反射。因此,如果您无法将生成的对象转换为编译时已知的对象,则必须再次对所有后续操作使用反射。
  • 在编译时绝对不知道(插件)。但是,我如何使用反射来进行示例中的复杂调用呢?我可以看到如何实例化一个部分,但看不到如何将其插入到调用链中。
  • 你必须获取链中的每个方法,取决于签名调用MakeGenericMethod 然后Invoke 它。
  • 是的,请试一试,如果需要,请提出具体的新问题。

标签: c# generics reflection types


【解决方案1】:

我想以下就足够了:

RegisterService(Type MyQueryType)
{
  Service.AddQuery(T =>
  {
    var service = new ServiceFactory.New();
    var method = service.GetType().GetMethod("AddQueryType").MakeGenericMethod(new Type[] { MyQueryType });
    var result = /*cast to AddQueryType return type*/method.Invoke(service, null);
    return result.Register(T).Create(); //if Create is void, remove the return
  });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-27
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多