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

本文关键字:迭代 内部 属性 | 更新日期: 2023-09-27 18:10:04

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
}

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

您需要指定您不只是需要公共属性,使用接受BindingFlags:

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

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

无参数重载只返回公共属性

您需要将呼叫中的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
}

根据MSDN,在反射API中不识别私有和内部。

要使用反射识别内部方法,请使用IsAssembly财产。来标识受保护的内部方法IsFamilyOrAssembly .

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

最后,你真的需要有内部属性吗…

通过指定GetProperties中的bindingflags:

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

使用BindingFlags

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

您可以通过查询NonPublic属性,然后通过"IsAssembly"过滤这些属性的get方法来获得类型的内部属性。

"内部受保护"属性的getter标记为"IsFamilyOrAssembly", "受保护"属性的getter标记为"IsFamily",以及"private"属性,标记为"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));
        }
    }