这与Invoking a method using reflection on a singleton object类似,但它有更深层次的背景。首先,我想说这是一个项目,我只是在玩想法,这是生产代码,并且项目采取了非常不同的路径,但这个问题仍然困扰着我,所以在这里它。
我有一个只包含对象实例的单例(尽管非静态基本上也是单例,但是由基础单例引用)
static CoreInstance()
{
Kernel = new Kernel();
Devices = new Devices();
Interfaces = new Interfaces();
Interoperability = new Interoperability();
Environment = new Environment();
Data = new Data();
}
通常情况下,这一切都很好,但是这些本身通常是容器对象,例如,我可能想要执行以下操作:
CoreInstance.Kernel.RaiseError("I'm an error lol!", ErrorLevel.Trivial);
-OR -
string username = CoreInstance.Environment.User.FullName;
但我是从用户命令控制台执行此操作,这是稍后SO问题的另一个讨论; - )
所以这里的主要问题是:如何编写递归反射函数来拆分类似这样的类路径字符串来执行方法/评估属性?
注意: 假设调用已经被分解为包含路径元素的有序字符串数组的结构,方法/属性的字符串以及参数的对象数组。
答案 0 :(得分:1)
如果你有两个包含属性/方法名称和每个参数的数组,那么我觉得这样的东西会起作用:
public object Execute(object target, IEnumerable<string> memberNames, IEnumerable<object[]> args)
{
if(memberNames.Count() == 0)
return target;
string currentMember = memberNames.First();
object[] currentArgs = args.First();
object value;
if (currentArgs.Length == 0)
{
//property
PropertyInfo pi = target.GetType().GetProperty(currentMember);
value = pi.GetValue(target, null);
}
else
{
//method
MethodInfo mi = target.GetType().GetMethod(currentMember);
value = mi.Invoke(target, currentArgs);
}
return Execute(value, memberNames.Skip(1), args.Skip(1));
}
因此,对于您的第一个示例,您可以这样称呼它:
string[] members = { "Kernel", "RaiseError" };
object[][] arguments = new[]{ new object[]{}, new object[]{"I'm an error lol!", ErrorLevel.Trivial}};
Execute(CoreInstance, members, arguments);