Type.InvokeMember 方法
1. 主方法
class Program
{
static void Main(string[] args)
{
ReflectUtils rf = new ReflectUtils();
rf.FNCMethod("ToString", null);
rf.FNCMethod("PrintNoPara", null);
rf.FNCMethod("PrintStatic", new object[] { "...PrintStatic" });
rf.FNCMethod("DoSthOnePara", new object[] { "...DoSthOnePara" });
rf.FNCMethod("DoSthTwoPara", new object[] { "...DoSthTwoPara", 3});
}
}
2. 中间类,执行ItemMethod 中的方法。可根据需要新增配置其他执行方法。
class ReflectUtils
{
public void FNCMethod(string methodName, object[] para)
{
ItemMethod iMethod = new ItemMethod();
iMethod.MethodCode(methodName, para);
}
}
3. 通过MethodCode,执行当前类中传入带参(para)的指定方法(methodName)
class ItemMethod
{
#region 测试用例
public ItemMethod()
{
Console.WriteLine("ctor:no para");
}
public ItemMethod(string x)
{
Console.WriteLine("ctor:string para");
}
Int32 myField;
public ItemMethod(ref Int32 x)
{
x *= 5;
}
public override String ToString()
{
Console.WriteLine("override ToString");
return myField.ToString();
}
public static void PrintNoPara()
{
Console.WriteLine("PrintNoPara");
}
public static void PrintStatic(string stm)
{
Console.WriteLine("PrintStatic:{0}", stm);
}
public void PrintNotStatic(string stm)
{
Console.WriteLine("PrintNotStatic:{0}", stm);
}
public void DoSthOnePara(string sth)
{
Console.WriteLine("DoSthOnePara:{0}", sth);
}
public void DoSthTwoPara(string sth, int ct)
{
Console.WriteLine("DoSth:{0},{1}", sth, ct);
}
public Int32 MyProp
{
get { return myField; }
set
{
if (value < 1)
throw new ArgumentOutOfRangeException("value", value, "value must be > 0");
myField = value;
}
}
#endregion
internal void MethodCode(string methodName, object[] para)
{
Assembly assembly = Assembly.LoadFile(Assembly.GetExecutingAssembly().Location);
string classTypeFullName = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName;
Type classType = assembly.GetType(classTypeFullName);
Object[] args = new Object[] { "ara1" };
Console.WriteLine("构造函数执行前x值:{0}.", args[0]);
Object classInstance = classType.InvokeMember(null,
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.CreateInstance, null, null, args);
Console.WriteLine("Type: " + classInstance.GetType().ToString());
Console.WriteLine("构造函数执行后x值:{0}.", args[0]);
#region 读取、写入字段.
classType.InvokeMember("myField",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.SetField, null, classInstance, new Object[] { 5 });
Int32 v = (Int32)classType.InvokeMember("myField",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.GetField, null, classInstance, null);
Console.WriteLine("myField: " + v);
#endregion
classType.InvokeMember(methodName, BindingFlags.InvokeMethod, null, classInstance, para);
#region 读取、写入属性。首先,尝试分配一个无效的值;然后分配一个有效的值;最后,获取值。
try
{
classType.InvokeMember("MyProp",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.SetProperty, null, classInstance, new Object[] { 0 });
}
catch (TargetInvocationException e)
{
if (e.InnerException.GetType() !=typeof(ArgumentOutOfRangeException))
throw;
Console.WriteLine("给MyProp分配的值无效:{0}",e.InnerException);
}
classType.InvokeMember("MyProp",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.SetProperty, null, classInstance, new Object[] { 2 });
v = (Int32)classType.InvokeMember("MyProp",
BindingFlags.DeclaredOnly |
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.GetProperty, null, classInstance, null);
Console.WriteLine("MyProp: " + v);
#endregion
}
}