36
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; }
}

I can iterate through the properties with the following loop, but it only shows public properties. I need all the properties.

foreach (PropertyInfo property in typeof(TestClass).GetProperties())
{
    //do something
}
Goran Obradovic
  • 8,951
  • 9
  • 50
  • 79
coder
  • 4,121
  • 14
  • 53
  • 88
  • Also see http://stackoverflow.com/questions/16024006/how-do-i-look-up-the-internal-properties-of-a-c-sharp-class-protected-protecte for a variant for this. – nawfal Dec 12 '13 at 11:26

6 Answers6

76

You need to specify that you don't just need the public properties, using the overload accepting BindingFlags:

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

Add BindingFlags.Static if you want to include static properties.

The parameterless overload only returns public properties.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 7
    Giving NonPublic and Instance will hide prop 1 and prop 2, you need both, NonPublic | Public for all properties – Marcin Deptuła Sep 27 '11 at 21:01
  • anyway to select only protected or internal? – Neville Nazerane Nov 30 '17 at 10:17
  • @NevilleNazerane: Not with binding flags, that I'm aware of. Just filter afterwards. – Jon Skeet Nov 30 '17 at 10:19
  • The piece it took me a little while to figure out is that once you're specifying any `BindingFlags`, you need to specify all `BindingFlags` necessary to identify the props you're interested in; specifically, without `BindingFlags.Instance` you won't match on any instance properties. (other languages' introspection led me to expect "Instance" to be assumed) – Tydaeus Dec 12 '22 at 16:17
12

You need to change the BindingFlags on your call to Type.GetProperties

Try:

var instanceProperties = typeof(TestClass).GetProperties(
    BindingFlags.Public |
    BindingFlags.NonPublic | 
    BindingFlags.Instance
);
foreach(var instanceProperty in instanceProperties) {
    // a little something something for the instanceProperty
}
jason
  • 236,483
  • 35
  • 423
  • 525
7

According to MSDN, private and internal are not recognized in Reflection API.

To identify an internal method using Reflection, use the IsAssembly property. To identify a protected internal method, use the IsFamilyOrAssembly.

If You are writing some test units You might want to take a look at InternalsVisibleTo attribute. It allows you to specify which assembly can see internal properties.

And finally, do You really need to have internal properties...

Filip Popović
  • 2,637
  • 3
  • 18
  • 18
  • yeah I do, it's wcf service class, I want the client to fill in some properties before sending it to the server, and rest of the properties to be filled in on the service. – coder Sep 27 '11 at 21:14
3

Use BindingFlags

foreach (PropertyInfo property in typeof(TestClass)
        .GetProperties(
            BindingFlags.Public |
            BindingFlags.NonPublic |
            BindingFlags.Instance))
{
    //do something
}
amit_g
  • 30,880
  • 8
  • 61
  • 118
3

by specifying what bindingflags in GetProperties:

foreach (PropertyInfo property in typeof(TestClass).GetProperties(
      BindingFlags.Instance|
      BindingFlags.Public|
      BindingFlags.NonPublic))
MatteKarla
  • 2,707
  • 1
  • 20
  • 29
2

You get the internal properties of a type by querying the NonPublic properties and then filtering the Get methods of these by "IsAssembly".

"internal protected" properties have their getters marked as "IsFamilyOrAssembly", "protected" properties as "IsFamily", and "private" properties as marked with "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));
        }
    }
lidqy
  • 1,891
  • 1
  • 9
  • 11