我在项目中有基类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 }
(但并非所有子类都使用此datetime参数)
好的,所以我们改变了(在特定的地方):
private void ImAChildMethod(string myString, int myInt )
到
private void ImAChildMethod(string myString, int myInt ,DateTime myDateTime )
问题出在哪里?
它在我们没有改变的地方引起了异常。
问题
我不想浏览所有子类并添加datetime的这个参数。 (并非所有子类都使用此参数)
有没有办法“预先识别”ImAChildMethod
执行/没有,DateTime myDateTime
,如果它有:使用它,如果没有 - 忽略新参数?
的Nb
我很确定我必须通过子类并添加可选参数......但我可能错了?
答案 0 :(得分:3)
可选参数实际上是一个编译时功能 - 除了通过反射使信息可用
之外,CLR和框架与它们几乎没什么关系。因此,虽然您可以检测到参数是可选的(使用ParameterInfo.IsOptional
)并获取默认值(使用ParameterInfo.DefaultValue
),但您需要明确地执行此操作 - InvokeMember
不要为你做。
您可能希望编写一个有效的InvokeMember
辅助方法,但处理可选参数...请记住,如果您只接受名称,您将会进入重载决议的尴尬业务。您可能希望将其限制为仅使用具有单个重载的名称,只是为了简单起见。
答案 1 :(得分:1)
您可以将可选参数添加到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 });
}
}