这个反射代码有什么问题?GetFields()返回一个空数组。

31

C#,.NET 2.0

这里是代码(我删除了所有特定于域的内容,但仍然返回空数组):

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ChildClass cc = new ChildClass();
            cc.OtherProperty = 1;

            FieldInfo[] fi = cc.GetType().GetFields();
            Console.WriteLine(fi.Length);
            Console.ReadLine();
        }
    }
    class BaseClass<T>
    {
        private int myVar;

        public int MyProperty
        {
            get { return myVar; }
            set { myVar = value; }
        }


    }

    class ChildClass : BaseClass<ChildClass>
    {
        private int myVar;

        public int OtherProperty
        {
            get { return myVar; }
            set { myVar = value; }
        }

    }
}
3个回答

77

GetFields()方法不带参数时返回公共字段。如果您想获取非公共字段,请使用:

cc.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic);

你可以选择任何适当的组合 - 但你必须指定至少一个InstanceStatic,否则它将不会找到任何一个。你可以同时指定两者以及公共字段,来获取所有内容:

cc.GetType().GetFields(BindingFlags.Instance | 
                       BindingFlags.Static |
                       BindingFlags.NonPublic |
                       BindingFlags.Public);

5
这是一个必须要注意的地方,你需要同时指定实例(Instance)和非公开(NonPublic)。 - Andrew Hare
1
谢谢你的回答!不过我有点难以理解。有人可以解释一下为什么对于私有字段,需要同时使用Instance或Static与NonPublic吗? - Zack
@rory.ap:是的,完全正确。 - Jon Skeet

12

由于该字段是私有的,您需要使用允许您指定BindingFlags.NonPublic的GetFields()重载。

要使其工作,请将其更改为:

FieldInfo[] fi = cc.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

5
您需要指定您想要的私有 (NonPublic) 字段。
更改为:
FieldInfo[] fi = cc.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance);

2
这将返回0个元素。此外,您需要包括BindingFlags.Instance以及BindingFlags.NonPublic。 - Reed Copsey

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