InvokeMethod可以用作可选参数吗



我在项目中有基类A

有许多子类继承自A

public class A
{
    public void Process(string myString1, int myInt1   )
        {
            Type type = this.GetType();
            type.InvokeMember("ImAChildMethod", System.Reflection.BindingFlags.InvokeMethod
                                                | System.Reflection.BindingFlags.NonPublic 
                                                | System.Reflection.BindingFlags.Instance,
                                                null, 
                                                this, 
                                                new object[] { myString1, myInt1  });
        }
}

子类:

public class B:A
{
   private void ImAChildMethod(string myString, int myInt )
    {
     Console.WriteLine (myInt + ","+myString);
    }
}

所以当我演示时:

new B().Process("aaa",15);我得到

15,aaa

很棒

几天过去了,现在我们需要发送——而不是:

new object[] { myString1, myInt1 }

但是

new object[] { myString1, myInt1 , MyDateTime }

(但是,并非所有子类都使用此日期时间参数)

好的,所以我们(在特定的地方)从:

 private void ImAChildMethod(string myString, int myInt )

 private void ImAChildMethod(string myString, int myInt ,DateTime myDateTime )

那么问题出在哪里呢?

它在我们没有改变的地方引起了异常。

问题

我不想浏览所有的子类并添加datetime的这个参数。(并非所有子类都使用此参数)

有没有一种方法可以"预先识别"ImAChildMethod有/没有,DateTime myDateTime,如果有:使用它,如果没有-忽略新参数?

Nb

我确信我必须遍历子类并添加可选参数。。。但我可能错了?

可选参数实际上是一种编译时功能-CLR和框架与它们几乎没有关系,只是通过反射使信息可用

因此,虽然您可以检测到参数是可选的(使用ParameterInfo.IsOptional)并获得默认值(使用ParameterInfo.DefaultValue),但您需要明确地这样做——InvokeMember不适合您。

您可能想要编写一个helper方法,它与InvokeMember类似,但处理可选参数。。。请记住,如果您只接受名称,您将陷入解决过载的尴尬境地。为了简单起见,您可能希望将其限制为仅使用具有单个重载的名称。

您可以将可选参数添加到Process方法中,然后检查子方法是否有两个或三个参数,然后相应地调用它:

public void Process(string myString1, int myInt1, DateTime date = default(DateTime))
{
     Type type = this.GetType();
     var flags =  BindingFlags.NonPublic | BindingFlags.Instance;
     var method = type.GetMethod("ImAChildMethod", flags);
     if(method.GetParameters().Length == 2)
     {
         type.InvokeMember("ImAChildMethod", System.Reflection.BindingFlags.InvokeMethod
                                           | System.Reflection.BindingFlags.NonPublic 
                                           | System.Reflection.BindingFlags.Instance,
                                           null, 
                                           this, 
                                           new object[] { myString1, myInt1  });
     } 
     else
     {
         type.InvokeMember("ImAChildMethod", System.Reflection.BindingFlags.InvokeMethod
                                           | System.Reflection.BindingFlags.NonPublic 
                                           | System.Reflection.BindingFlags.Instance,
                                           null, 
                                           this, 
                                           new object[] { myString1, myInt1,vdate  });
     }
}

相关内容

  • 没有找到相关文章