繁体   English   中英

c#reflectin:为给定的类实例调用具有泛型类型和泛型参数的方法

[英]c# reflectin: calling method with generic type and generic parameter for given instance of class

我需要使用反射调用具有泛型参数的泛型方法,其中泛型类型作为字符串中的参数提供。 网上有一些泛型和反射的例子,但我仍然无法让它工作。

无反射:

        string typeName = "EventType"; // as param1 -> type name
        string content = ""; //as param2 -> some json cotnent

        IMyBus bus = new MyBus();
        switch (typeName)
        {
            case "EventType":
                IEventType content = Deserialize<IEventType>(content);
                bus.Publish<IEventType>(content);
                break;
            case "EventType2":
                IEventType2 content2 = Deserialize<IEventType2>(content);
                bus.Publish<IEventType2>(content2);
                break;
        }

相反,我想使用反射重写它以提供更多的 EventType,而无需重写此特定代码。

以下是我的测试类:

 public interface IMyBus **//TWO METHODS HERE, WE NEED TO CALL FIRST ONE!**
 {
     void Publish<T>(T message, CancellationToken cancellationToken = default(CancellationToken)) where T : class; //THIS SHOULD BE CALLED
     void Publish<T>(T message, int i, CancellationToken cancellationToken = default(CancellationToken)) where T : class;
  }

  // Interface implementation
  public class MyBus : IMyBus
  {
      public void Publish<T>(T message, CancellationToken cancellationToken = default(CancellationToken)) where T : class
      {  ... }
      public void Publish<T>(T message, int i, CancellationToken cancellationToken = default(CancellationToken)) where T : class
      {  ... }
    }

    public interface IEventType { int forTest { get; set; } }

    public class EventType : IEventType { public int forTest { get; set; } }

    public interface IEventType2 { int forTest2 { get; set; } }

    public class EventType2 : IEventType2 { public int forTest2 { get; set; } }

这是我已经尝试过的:

 IMyBus bus = new MyBus();
 EventType content = new EventType() { forTest = 1 };
 var eventTypeName = $"ConsoleApp.EventType";
 var iEventTypeName = $"ConsoleApp.IEventType";

 Type intEvType = Type.GetType(iEventTypeName);
 Type evType = Type.GetType(eventTypeName);

 MethodInfo openGenericMethod = typeof(IMyBus).GetMethod("Publish", 2, new Type[] { intEvType, typeof(CancellationToken) });
 MethodInfo closedGenericMethod = openGenericMethod.MakeGenericMethod(evType);
 object o2 = closedGenericMethod.Invoke(bus, new object[] { content });

但这是错误的。 openGenericMethod始终为空。

我认为对于这种情况,最好根据名称和参数数量手动查找方法:


 MethodInfo openGenericMethod = typeof(IMyBus).GetMethods()
                                .SingleOrDefault(m => m.Name == "Publish" 
                                                && m.IsGenericMethod 
                                                && m.GetParameters().Count() == 2);


但是您将使用optional参数调用方法。 这就是为什么你应该使用其他Invoke方法来定义绑定标志:

MethodInfo closedGenericMethod = openGenericMethod.MakeGenericMethod(evType);

closedGenericMethod.Invoke(bus, BindingFlags.OptionalParamBinding, null, 
new object[] { content, Type.Missing }, CultureInfo.InvariantCulture);

我已经在测试 ConsoleApp 中对其进行了测试。 有用。

暂无
暂无

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

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