【问题标题】:c# - How to create Generic T from objectName?c# - 如何从 objectName 创建 Generic T?
【发布时间】:2020-05-21 14:51:42
【问题描述】:

我创建了一个FetchData 方法,它返回IList<object>,它以objectName(string) 作为参数(我们要返回列表的对象的名称)。

Task<IList<object>> FetchData(string processGuiId, string objectName);

我正在从FetchData(string processGuiId, string objectName) 调用网关方法以从源获取数据。

_gateway.ReadByQueryAsync<T>();

对于ReadByQueryAsync 方法,我如何从objectName 获得T

【问题讨论】:

  • 你能添加一些代码吗?
  • typeof(T).Name?如果我理解正确的话,其他方式是不可能的。
  • 你不能。 T 在编译时指定,而objectName 在运行时提供。是否有理由需要为类型名称使用字符串?
  • @JohnathanBarclay 我将 objectName 作为 API 中的参数之一,它正在调用 FetchData 方法。

标签: c# .net generics system.reflection


【解决方案1】:

您不能“从 objectName 创建 Generic T”,但可以从类型构造泛型方法。

我认为你正在寻找MethodInfo.MakeGenericMethod 用法会是这样的:

// somehow get fully qualified name from objectName
vat type = Type.GetType("fully qualified name"); 
var mi = _gateway.GetType().GetMethod("ReadByQueryAsync").MakeGenericMethod(type);

并调用,例如:

mi.Invoke(_gateway, null)

或使用expression trees 构建一个 lambda 并缓存它。

Enumerable.First() 为例:

var mi = typeof(Enumerable)
    // cause multiple "First" methods
    .GetMethods()
    .Where(mi => mi.Name == "First" && mi.GetParameters().Length == 1)
    .First();
var type = Type.GetType("System.Int32");
var constructed = mi.MakeGenericMethod(type);
var obj = new[] { 1, 2 };
// you will have another order of parameters in Invoke if ReadByQueryAsync is instance method
var x = constructed.Invoke(
    null, // null cause First is extension method, should be obj if instance
    new[] { obj } // should be null for parameterless instance method
    ); // x = 1

【讨论】:

  • 我会试试这个
猜你喜欢
  • 1970-01-01
  • 2017-08-06
  • 1970-01-01
  • 2015-09-03
  • 1970-01-01
  • 1970-01-01
  • 2018-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多