如何在c#中迭代内部属性

时间:2011-09-27 20:56:53

标签: c# reflection properties access-modifiers

public class TestClass
{
        public string property1 { get; set; }
        public string property2 { get; set; }

        internal string property3 { get; set; }
        internal string property4 { get; set; }
        internal string property5 { get; set; }
}

我可以使用以下循环遍历属性,但它只显示公共属性。我需要所有的属性。

foreach (PropertyInfo property in typeof(TestClass).GetProperties())
{
    //do something
}

6 个答案:

答案 0 :(得分:56)

您需要使用overload接受BindingFlags来指定您不仅需要公共属性:

foreach (PropertyInfo property in typeof(TestClass)
             .GetProperties(BindingFlags.Instance | 
                            BindingFlags.NonPublic |
                            BindingFlags.Public))
{
    //do something
}

如果要包含静态属性,请添加BindingFlags.Static

无参数重载仅返回公共属性。

答案 1 :(得分:10)

您需要将通话中的BindingFlags更改为Type.GetProperties

尝试:

var instanceProperties = typeof(TestClass).GetProperties(
    BindingFlags.Public |
    BindingFlags.NonPublic | 
    BindingFlags.Instance
);
foreach(var instanceProperty in instanceProperties) {
    // a little something something for the instanceProperty
}

答案 2 :(得分:5)

根据MSDN,在Reflection API中无法识别私人和内部。

  

要使用Reflection识别内部方法,请使用IsAssembly   属性。要识别受保护的内部方法,请使用   IsFamilyOrAssembly。

如果您正在编写一些测试单元您可能需要查看InternalsVisibleTo属性。它允许您指定哪个程序集可以看到内部属性。

最后,你真的需要内部属性......

答案 3 :(得分:3)

使用BindingFlags

foreach (PropertyInfo property in typeof(TestClass)
        .GetProperties(
            BindingFlags.Public |
            BindingFlags.NonPublic |
            BindingFlags.Instance))
{
    //do something
}

答案 4 :(得分:3)

通过在GetProperties中指定哪些bindingflags:

foreach (PropertyInfo property in typeof(TestClass).GetProperties(
      BindingFlags.Instance|
      BindingFlags.Public|
      BindingFlags.NonPublic))

答案 5 :(得分:0)

通过查询NonPublic属性,然后通过“ IsAssembly”过滤这些类型的Get方法,可以获取类型的内部属性。

“内部受保护”属性的吸气剂标记为“ IsFamilyOrAssembly”,“受保护”属性的标记为“ IsFamily”,并且 标记为“ IsPrivate”的“私有”属性:

    public class TestClass
    {
        public string Property1 { get; set; }
        private string Property2 { get; set; }

        public string Property9 { get; set; }
        private string Property10 { get; set; }

        protected internal string Property3 { get; set; }
        protected string Property4 { get; set; }
        internal string Property5 { get; set; }

        protected internal int Property6 { get; set; }
        protected int Property7 { get; set; }
        internal int Property8 { get; set; }

        internal static void ShowPropertyAccessScope(Type t)
        {

            foreach (var prop in t.GetProperties(BindingFlags.Instance | BindingFlags.Public))
            {
                Console.WriteLine("{0,-28} {1,15}", "Public property:", prop.Name);
            }

            var nonPublic = t.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic);

            foreach (var prop in nonPublic.Where(p => p.GetGetMethod(true)?.IsAssembly == true))
            {
                Console.WriteLine("{0,-28} {1,15}", "Internal property:", prop.Name);
            }

            foreach (var prop in nonPublic.Where(p => p.GetGetMethod(true)?.IsFamilyOrAssembly == true))
            {
                Console.WriteLine("{0,-28} {1,15}", "Internal protected property:", prop.Name);
            }

            foreach (var prop in nonPublic.Where(p => p.GetGetMethod(true)?.IsFamily == true))
            {
                Console.WriteLine("{0,-28} {1,15}", "Protected property:", prop.Name);
            }

            foreach (var prop in nonPublic.Where(p => p.GetGetMethod(true)?.IsPrivate == true))
            {
                Console.WriteLine("{0,-28} {1,15}", "Private property:", prop.Name);
            }
        }
        static void Main() 
        {
            ShowPropertyAccessScope(typeof(TestClass));
        }
    }