通过反射来构造类的实例、执行类的方法、属性设置等。
// Comment out the following line to test,
// bind, and invoke as separate steps.
#define BindAndInvokeTogether
using System;
using System.Reflection;
using System.Threading;
// This class is used to demonstrate reflection. It has a
// a field, a constructor, a method, a property, and an event.
class SomeType
{
Int32 someField;
public SomeType(ref Int32 x) { x *= 2; }
public override String ToString() { return someField.ToString(); }
public Int32 SomeProp
{
get { return someField; }
set
{
if (value < 1)
throw new ArgumentOutOfRangeException("value", value, "value must be > 0");
someField = value;
}
}
public event ThreadStart SomeEvent;
private void NoCompilerWarnings()
{
SomeEvent.ToString();
}
}
class App
{
static void Main()
{
Type t = typeof(SomeType);
BindingFlags bf = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
#if BindAndInvokeTogether
// Construct an instance of the Type.
Object[] args = new Object[] { 12 }; // Constructor arguments
Console.WriteLine("x before constructor called: " + args[0]);
Object obj = t.InvokeMember(null,bf | BindingFlags.CreateInstance, null, null, args);
Console.WriteLine("Type: " + obj.GetType().ToString());
Console.WriteLine("x after constructor returns: " + args[0]);
// Read and write to a field.
t.InvokeMember("someField",bf | BindingFlags.SetField, null, obj, new Object[] { 5 });
Int32 v = (Int32)t.InvokeMember("someField",bf | BindingFlags.GetField, null, obj, null);
Console.WriteLine("someField: " + v);
// Call a method.
String s = (String)t.InvokeMember("ToString",bf | BindingFlags.InvokeMethod, null, obj, null);
Console.WriteLine("ToString: " + s);
// Read and write a property.
try
{
t.InvokeMember("SomeProp",bf | BindingFlags.SetProperty, null, obj, new Object[] { 0 });
}
catch (TargetInvocationException e)
{
if (e.InnerException.GetType() !=
typeof(ArgumentOutOfRangeException))
throw;
Console.WriteLine("Property set catch.");
}
t.InvokeMember("SomeProp",bf | BindingFlags.SetProperty, null, obj, new Object[] { 2 });
v = (Int32)t.InvokeMember("SomeProp",bf | BindingFlags.GetProperty, null, obj, null);
Console.WriteLine("SomeProp: " + v);
// NOTE: InvokeMember doesn’t support events.
#else
// Construct an instance.
ConstructorInfo ctor = t.GetConstructor(new Type[] { Type.GetType("System.Int32&") });
Object[] args = new Object[] { 12 }; // Constructor arguments
Console.WriteLine("x before constructor called: " + args[0]);
Object obj = ctor.Invoke(args);
Console.WriteLine("Type: " + obj.GetType().ToString());
Console.WriteLine("x after constructor returns: " + args[0]);
// Read and write to a field.
FieldInfo fi = obj.GetType().GetField("someField", bf);
fi.SetValue(obj, 33);
Console.WriteLine("someField: " + fi.GetValue(obj));
// Call a method.
MethodInfo mi = obj.GetType().GetMethod("ToString", bf);
String s = (String)mi.Invoke(obj, null);
Console.WriteLine("ToString: " + s);
// Read and write a property.
PropertyInfo pi =obj.GetType().GetProperty("SomeProp", typeof(Int32));
foreach (MethodInfo m in pi.GetAccessors())
Console.WriteLine(m);
try
{
pi.SetValue(obj, 0, null);
}
catch (TargetInvocationException e)
{
if (e.InnerException.GetType() !=
typeof(ArgumentOutOfRangeException))
throw;
Console.WriteLine("Property set catch.");
}
pi.SetValue(obj, 2, null);
Console.WriteLine("SomeProp: " + pi.GetValue(obj, null));
// Add and remove a delegate from the event.
EventInfo ei = obj.GetType().GetEvent("SomeEvent", bf);
Console.WriteLine("AddMethod: " + ei.GetAddMethod());
Console.WriteLine("RemoveMethod: " + ei.GetRemoveMethod());
Console.WriteLine("EventHandlerType: " + ei.EventHandlerType);
ThreadStart ts = new ThreadStart(Main);
ei.AddEventHandler(obj, ts);
ei.RemoveEventHandler(obj, ts);
#endif
Console.ReadKey();
}
}
输出:(注意会执行一次异常处理,输出Property set catch.)
x before constructor called: 12
Type: SomeType
x after constructor returns: 24
someField: 5
ToString: 5
Property set catch.
SomeProp: 2
注释第一行的#define BindAndInvokeTogether后输出:(也会执行一次异常处理,因为输出了Property set catch)
x before constructor called: 12
Type: SomeType
x after constructor returns: 24
someField: 33
ToString: 33
Int32 get_SomeProp()
Void set_SomeProp(Int32)
Property set catch.
SomeProp: 2
AddMethod: Void add_SomeEvent(System.Threading.ThreadStart)
RemoveMethod: Void remove_SomeEvent(System.Threading.ThreadStart)
EventHandlerType: System.Threading.ThreadStart