public abstract class MyBase
{
protected string _foo = "Hello";
protected string Foo
{
get {
return _foo;
}
}
}
public class MyChild : MyBase
{
public MyChild() {
Console.WriteLine("Hello from MyChild: {0}", Foo);
}
}
public static class ObjectExtensions
{
public static T ReadProperty<T>(this object obj, string name) {
Type tp = obj.GetType();
// This loop is for testing purposes only.
foreach (var t in tp.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy)) {
Console.WriteLine("Property name: {0}: Can read: {1}", t.Name, t.CanRead);
// OUTPUT: Property name: Foo: Can read: True
}
var pi = tp.GetProperty(name, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
if (pi == null) {
Console.WriteLine("Property not found!");
return default(T);
}
if (pi.GetType() is T) {
return (T)pi.GetValue(obj);
}
try {
return (T)Convert.ChangeType(pi.GetValue(obj), typeof(T));
} catch (InvalidCastException) {
return default(T);
}
}
}
public class Program
{
public static void Main()
{
var c = new MyChild();
Console.WriteLine("Foo from MyChild: {0}", c.ReadProperty<string>("Foo"));
}
}
我尝试使用其他BindingFlags
,但始终会导致以下异常:
Hello from MyChild: Hello
Property name: Foo: Can read: True
Run-time exception (line 25): Attempt by method 'ObjectExtensions.ReadProperty<System.__Canon>(System.Object, System.String)' to access method 'MyBase.get_Foo()' failed.
Stack Trace:
[System.MethodAccessException: Attempt by method 'ObjectExtensions.ReadProperty<System.__Canon>(System.Object, System.String)' to access method 'MyBase.get_Foo()' failed.]
at System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, RuntimeMethodHandleInternal method, RuntimeType parent, UInt32 invocationFlags)
at System.RuntimeMethodHandle.PerformSecurityCheck(Object obj, IRuntimeMethodInfo method, RuntimeType parent, UInt32 invocationFlags)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at System.Reflection.PropertyInfo.GetValue(Object obj)
at ObjectExtensions.ReadProperty[T](Object obj, String name) :line 25
at Program.Main() :line 57
我做错了什么?