Cyg*_*gon 7 c# reflection properties backing-field
在C#中,如果使用Type.GetFields()表示派生类的类型,它将返回a)派生类中所有显式声明的字段,b)派生类中自动属性的所有支持字段和c)基础中所有显式声明的字段类.
为什么缺少基类中自动属性的d)支持字段?
例:
public class Base {
public int Foo { get; set; }
}
public class Derived : Base {
public int Bar { get; set; }
}
class Program {
static void Main(string[] args) {
FieldInfo[] fieldInfos = typeof(Derived).GetFields(
BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance | BindingFlags.FlattenHierarchy
);
foreach(FieldInfo fieldInfo in fieldInfos) {
Console.WriteLine(fieldInfo.Name);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这将只显示Bar的支持字段,而不是Foo.
作为背景场的场对反射没有影响.支持字段的唯一相关属性是它们是私有的.
即使您使用,反射函数也不会返回基类的私有成员FlattenHierarchy.您需要在类层次结构上手动循环,并在每个层次上请求私有字段.
我认为这FlattenHierarchy是为了让所有成员都能看到你所看到的类中的代码.因此,基础成员可以由更多派生类中具有相同名称的成员隐藏/隐藏,并且私有成员根本不可见.
这是使用HashSet的修订版本:
public static FieldInfo[] GetFieldInfosIncludingBaseClasses(Type type, BindingFlags bindingFlags)
{
FieldInfo[] fieldInfos = type.GetFields(bindingFlags);
// If this class doesn't have a base, don't waste any time
if (type.BaseType == typeof(object))
{
return fieldInfos;
}
else
{ // Otherwise, collect all types up to the furthest base class
var currentType = type;
var fieldComparer = new FieldInfoComparer();
var fieldInfoList = new HashSet<FieldInfo>(fieldInfos, fieldComparer);
while (currentType != typeof(object))
{
fieldInfos = currentType.GetFields(bindingFlags);
fieldInfoList.UnionWith(fieldInfos);
currentType = currentType.BaseType;
}
return fieldInfoList.ToArray();
}
}
private class FieldInfoComparer : IEqualityComparer<FieldInfo>
{
public bool Equals(FieldInfo x, FieldInfo y)
{
return x.DeclaringType == y.DeclaringType && x.Name == y.Name;
}
public int GetHashCode(FieldInfo obj)
{
return obj.Name.GetHashCode() ^ obj.DeclaringType.GetHashCode();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6601 次 |
| 最近记录: |