【问题标题】:how do I iterate through internal properties in c#如何在c#中遍历内部属性
【发布时间】:2011-11-26 09:30:51
【问题描述】:
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# reflection properties access-modifiers


【解决方案1】:

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

“内部受保护”属性的 getter 标记为“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));
        }
    }

【讨论】:

    【解决方案2】:

    使用BindingFlags

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

    【讨论】:

      【解决方案3】:

      根据MSDN,反射 API 无法识别私有和内部。

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

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

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

      【讨论】:

      • 是的,是wcf服务类,我希望客户端在发送到服务器之前填写一些属性,其余的属性要在服务上填写。
      【解决方案4】:

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

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

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

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

      【讨论】:

      • Giving NonPublic 和 Instance 将隐藏 prop 1 和 prop 2,你需要两者,NonPublic |对所有属性公开
      • 还是只选择受保护的还是内部的?
      • @NevilleNazerane:我知道没有绑定标志。事后过滤。
      【解决方案5】:

      通过在 GetProperties 中指定哪些绑定标志:

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

      【讨论】:

        【解决方案6】:

        您需要将通话中的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
        }
        

        【讨论】:

        • 是的,我还必须添加 BindingFlags.Public
        猜你喜欢
        • 2021-09-24
        • 2011-12-30
        • 2018-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-06
        • 2015-02-02
        • 2018-11-17
        相关资源
        最近更新 更多