获取派生类型的字段。

7

我试图反映派生类型中的字段,但它返回了基本类型的字段。

public class basetype
{
    string basevar;
}

public class derivedtype : basetype
{
    string derivedvar;
}

在某些函数中:

derivedtype derived = new derivedtype();

FieldInfo[] fields = derived.GetType().GetFields();

这将返回basevar,但不包括derivedvar。我尝试过所有不同的绑定方式,但似乎并没有什么区别。
此外,我是在App_Code中的ASP.NET中进行此操作,其中basevar在App_Code中定义,而derivedvar是在App_Controls中定义的用户控件,类型不在范围内。

1
你的代码对我起作用了(我看到了derivedvar),一旦我将字段公开以将它们暴露给GetFields()。 你确定你的类层次结构吗? 你尝试在独立项目中使用上面的代码了吗? - Michael Petrotta
1
在上述代码中,derivedtype 并没有从 basetype 派生出来,因此您应该只看到 derivedvar(使用 BindingFlags.NonPublic),但不包括 basevar - dtb
@dtb:我错过了那个。刚刚用正确的推导重新运行了一遍,结果相同。 - Michael Petrotta
没错,在我的代码示例中我漏掉了导数。我已经更改了它,感谢你的帮助。 - KenEucker
2个回答

11

现在的代码只能返回空值,因为默认绑定仅适用于公共字段。

当前情况下,derivedtype并不是从basetype派生来的。

使用以下代码:

FieldInfo[] fields = derived.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

我刚在 LINQPad 中检查了一下,它返回 derivedvar。

如果我将 derivedtype 更改为从 basetype 派生,那么我可以使用以下方式获取两个字段:

FieldInfo[] fields = derived.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance).Concat(derived.GetType().BaseType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)).ToArray();

这就是了,我试图获取私有成员,但在将成员设置为私有之前无法使其正常工作。这是我的疏忽,非常抱歉。 - KenEucker
在我的情况下,上述行需要进行小的调整: - Mark

5

反射有点奇怪。

如果成员是公共的,那么它们在整个层次结构中都可见。

如果成员是非公共的,则必须指定BindingFlags.NonPublic,您将仅获得使用的类型的那些成员。继承的成员不可见。如果要查看类型的所有非公共成员,则必须沿着继承链向上移动。


这并不是“奇怪”的,而恰恰是应该这样的。想象一下,如果您可以为派生类中的字段赋予任何名称,除了基类中的私有字段名称,那么该私有字段就不再那么私有了。 - dtb
请纠正我,但我认为你误解了这个问题。我的问题是尝试获取派生类的成员,它已经从基类返回继承的成员,但没有返回任何派生类的成员。我尝试过BindingFlags.NonPublic,但仍然不起作用。 - KenEucker
@Epic720:正如我之前提到的,我怀疑你的类层次结构并不像你所描述的那样(实际上它不可能是这样的——你在示例中展示的两个类甚至没有任何关系!)。你能否将你的真实层次结构简化为可以发布的内容? - Michael Petrotta
@dtb:你说得对,它的确是应该这样的。只是不太直观。如果这是你第一次尝试反射,并且没有仔细考虑,那么你可能会觉得有些奇怪。 - Tergiver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接