Dus*_*vis 24 .net c# reflection
这是结构:
MyClass:SuperClass2
SuperClass2:SuperClass1
superClass2位于Product.Web中,SuperClass1位于.NET System.Web程序集中
我试图强制一个值进入SuperClass1上的私有bool字段.但无论我尝试什么,我都无法让领域从反思回来.
我使用以下代码与不同的BindingFlag组合,但到目前为止没有任何工作.SuperClass1是一个抽象类.
((SuperClass1)this).GetType().GetFields(System.Reflection.BindingFlags.NonPublic);
Run Code Online (Sandbox Code Playgroud)
注意: 当我使用GetProperties()时,我得到了一个很好的大清单,但是当我指定任何绑定标志时,即使有匹配的属性,我什么也得不到.这是怎么回事?
此外,该字段未标记为内部
显然我会使用GetField(字符串名称,BindingFlags),但我甚至无法使GetFlags()工作.
更新:我已经尝试按照建议添加BindingFlags.Instance,但它不起作用(无论如何都是预期的).我找回了来自SuperClass1类继承自的2个字段.与GetField一起使用时返回null(字符串名称,标志)
这是我试图获取该字段的基类的代码
public abstract class BaseValidator : Label, IValidator
{
private bool propertiesChecked;
...
}
Run Code Online (Sandbox Code Playgroud)
Bro*_*ass 35
您可以手动进入继承链以获取基本字段:
鉴于这些类:
class SuperClass1
{
private int myField;
}
class SuperClass2 : SuperClass1
{
}
class MyClass : SuperClass2
{
}
Run Code Online (Sandbox Code Playgroud)
这应该工作:
var myObj = new MyClass();
var myField = typeof(MyClass).BaseType
.BaseType
.GetField("myField", BindingFlags.Instance | BindingFlags.NonPublic);
Run Code Online (Sandbox Code Playgroud)
在这个SO答案中有一个更通用的解决方案:不从GetType()获取字段.具有BindingFlag.Default的GetFields
扩展方法:
/// <summary>
/// Returns the FieldInfo matching 'name' from either type 't' itself or its most-derived
/// base type (unlike 'System.Type.GetField'). Returns null if no match is found.
/// </summary>
public static FieldInfo GetPrivateField(this Type t, String name)
{
const BindingFlags bf = BindingFlags.Instance |
BindingFlags.NonPublic |
BindingFlags.DeclaredOnly;
FieldInfo fi;
while ((fi = t.GetField(name, bf)) == null && (t = t.BaseType) != null)
;
return fi;
}
Run Code Online (Sandbox Code Playgroud)
与BrokenGlass的解决方案类似,你可以这样做,使它更通用:
class Base { private int _baseField; }
class Derived : Base { }
class Mine : Derived { }
Run Code Online (Sandbox Code Playgroud)
然后:
Type t = typeof(Mine);
FieldInfo fi = null;
while (t != null)
{
fi = t.GetField("_baseField", BindingFlags.Instance | BindingFlags.NonPublic);
if (fi != null) break;
t = t.BaseType;
}
if (fi == null)
{
throw new Exception("Field '_baseField' not found in type hierarchy.");
}
Run Code Online (Sandbox Code Playgroud)
作为一种实用方法:
public static void SetField(object target, string fieldName, object value)
{
if (target == null)
{
throw new ArgumentNullException("target", "The assignment target cannot be null.");
}
if (string.IsNullOrEmpty(fieldName))
{
throw new ArgumentException("fieldName", "The field name cannot be null or empty.");
}
Type t = target.GetType();
FieldInfo fi = null;
while (t != null)
{
fi = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
if (fi != null) break;
t = t.BaseType;
}
if (fi == null)
{
throw new Exception(string.Format("Field '{0}' not found in type hierarchy.", fieldName));
}
fi.SetValue(target, value);
}
Run Code Online (Sandbox Code Playgroud)
然后:
Mine m = new Mine();
SetField(m, "_baseField", 10);
Run Code Online (Sandbox Code Playgroud)