【问题标题】:Passing return value from invoked method to generic method将调用方法的返回值传递给泛型方法
【发布时间】:2019-11-19 09:52:44
【问题描述】:

我正在构建一个模块化 API,人们可以通过使用我的自定义属性标记他们的资源方法来使用他们自己的端点做出贡献。如果我用我的应用程序加载他们的 dll,他们的方法就可用。当请求资源时,我的程序从他们(在他们自己的类中)创建的方法中获取数据集合,并在以 JSON 格式发送序列化响应之前对它们应用排序和过滤(可能使用 DynamicLinq)。这些类上的所有公共字段(可能还有属性)都被视为 api 中的字段。

正如您可能意识到的,我只在运行时知道这些数据类的类型,但我希望我可以调用端点方法并将返回的IEnumerable<SomeUnknownType> 传递给我的过滤方法。我对泛型和 C# 的内部工作还是有点陌生​​。

我的想法范围从纯粹的反射、序列化到 JSON,然后解析字符串,再到现在的泛型。发现了这个问题: Using reflection to serialize files,其中包含一些“hack”,但我不太了解它,无法让它工作。

只有当集合使用通用 T 时,我才会让 DynamicLinq 对我的数据进行排序。

哦,我被困在 .Net 3.5 上,所以没有动态。

public static void Main(string[] args)
{
    //Retrieves MethodInfo from a 'MethodHub' class, collected via Reflection at runtime.
    MethodInfo endpointMethod = MethodHub.GetEndpointMethod();

    // Invokes EndpointMethod. I know it will return an IEnumerable<T>, where T is unknown.
    object requestedList = method.Invoke(null, null);

    // The list should be passed to the 'Filter'-method, but it needs to be cast to its actual type first, so...
    Filter(requestedList);
}

// This is the method I want to pass the return value 'list' from 'EndpointMethod'
public static void IEnumerable<T> Filter<T>(IEnumerable<T> inputList)
{
    // Filtering inputList with DynamicLinq
}

这是在某个未知的类中。

// This is the 'EndpointMethod'. The type of this IEnumerable<> is known only at runtime.
public static IEnumerable<SomeUnknownType> EndpointMethod()
{
    IEnumerable<SomeUnknownType> list = new List<SomeUnknownType>();

    return list;
}

【问题讨论】:

  • SomeMethodSomeType 的成员,还是与Main 属于同一类,还是在其他地方?当您为返回类型说IEnumerable&lt;SomeUnknownType&gt; 时,是不是应该是IEnumerable&lt;SomeType&gt; 的错字?另外,你听说过MEF吗?它允许您在运行时加载程序集并使用类似于您正在执行的属性绑定插件;无需重新发明轮子!
  • SomeMethod 是使用自定义属性修饰的方法之一。不是SomeType的成员,也不是这里的Main。是的,错字已更正,谢谢!我不知道MEF。酷的东西!但是我的程序已经注入到另一个程序中,我怀疑让它与像 MEF 这样的东西一起工作会很困难。
  • 谢谢!那么SomeType 是否继承自SomeUnknownType,或者当您创建列表时这是另一个错字?您遇到的问题是GetSomeMethod() 调用 - 您需要知道使用反射或类似方法获取方法的内容是什么?如果是这种情况,您有哪些关于可用于查找它的方法的信息——它的名称、参数类型、返回类型、定义它的类型等?还是您的代码的其他部分有问题?
  • 哇,这很难说!所以,我编辑了上面的代码。我的问题在于我想以 'IEnumerable

标签: c# .net-3.5


【解决方案1】:

调用GetEndpointMethod后,可以通过requestedList.GetType().GetGenericArguments().First()获取requestList的T类型。试试这个代码:

public static void Main(string[] args)
{
      MethodInfo endpointMethod = typeof(Main).GetMethod("EndpointMethod").MakeGenericMethod(typeof(int)); //Replace Main with your class name

      object requestedList = endpointMethod.Invoke(null, null);

      var result = typeof(Main).GetMethod("Filter").MakeGenericMethod(requestedList.GetType().GetGenericArguments().First()).Invoke(null, new object[]{ requestedList });  //Replace Main with your class name
}

public static IEnumerable<T> Filter<T>(IEnumerable<T> inputList)
{
  return inputList;
}

public static IEnumerable<T> EndpointMethod<T>()
{
  IEnumerable<T> list = new List<T>();

  return list;
}

【讨论】:

  • 非常感谢!它现在正在工作!但是,我不得不删除MakeGenericMethod(typeof(int)) 中的参数typeof(int)。我不知道你把它放在那里的原因,但它只有在没有它的情况下才能工作。
  • 我正在使用 List 进行测试,但忘记将其删除 :)
猜你喜欢
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多