Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
c#reflectin:为类的给定实例调用泛型类型和泛型参数的方法_C#_Reflection - Fatal编程技术网

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

c#reflectin:为类的给定实例调用泛型类型和泛型参数的方法,c#,reflection,C#,Reflection,我需要使用反射调用带有泛型参数的泛型方法,其中泛型类型作为字符串中的参数提供。在线上有一些泛型和反射的例子,但我仍然无法让它起作用 不假思索: string typeName = "EventType"; // as param1 -> type name string content = ""; //as param2 -> some json cotnent IMyBus bus = new MyBus(); sw

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

不假思索:

        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;
        }

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

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


MethodInfo openGenericMethod=typeof(IMyBus).GetMethods()
.SingleOrDefault(m=>m.Name==“发布”
&&m.IsGenericMethod
&&m.GetParameters().Count()==2);
但您将使用
可选的
参数调用方法。这就是为什么您应该使用其他
Invoke
方法来定义绑定标志:

MethodInfo closedGenericMethod=openGenericMethod.MakeGenericMethod(evType);
closedGenericMethod.Invoke(总线,BindingFlags.OptionalParamBinding,null,
新对象[]{content,Type.Missing},CultureInfo.InvariantCulture);

我已经在测试控制台App中测试过了。它可以工作。

如果我还有第三个Publish方法,它也有两个参数:Task Publish(对象值,CancellationToken CancellationToken=default(CancellationToken)),其中T:class?(在我的示例中是IMyBus,但实际上我有来自MassTransit assembly的IPublishEndpoint)您可以检查第一个参数类型
m.GetParameters().first().ParameterType==typeof(object)
@renathy它对您有帮助吗?或者我应该考虑更好地实现我的想法吗?
 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 });