In this article, we are going to learn how to get the list of properties in C#, and also how to use the BindingFlags to filter the properties to retrieve.
We have a lot to cover. Let’s start it.
Prepare The Environment
First, let’s create a console application using the Visual Studio wizard or the dotnet new console
command.
Once our project is ready, let’s create a Person
class and define some properties:
public class Person { public string FirstName { get; set; } = default!; public string LastName { get; set; } = default!; public int Age { get; set; } }
We will use this class and its properties throughout this entire article.
Additionally, let’s create a method to print every property:
public void PrintProperties(PropertyInfo[] properties) { foreach (var item in properties) { Console.WriteLine($" * {item.Name}"); } Console.WriteLine("--"); Console.WriteLine(); }
As an input parameter, this method receives a PropertyInfo[]
array with every property to print. Then we iterate through each element in the array and print the name of the property to the console.
Get The List of Properties
The first step consists of adding the reflection namespace to our application.
Once we have the Person
class ready and the reflection namespace imported, let’s create a RetrieveProperties()
method to retrieve every property from an instance:
public PropertyInfo[] RetrieveProperties(object obj) { var type = obj.GetType(); return type.GetProperties(); }
First, as an input parameter, this method receives an object instance (obj
) from which we want to get every property. Then, we use the GetType()
method to get the instance type from this object and store it in the type
object.
Finally, we return the GetProperties()
result to print it later using the PrintProperties()
method.
Now, let’s call this method sending a Person
instance as a parameter:
properties = propertiesRetriever.RetrieveProperties(new Person());
Subsequently, let’s call the PrintProperties()
method:
propertiesRetriever.PrintProperties(properties);
After that we have the result:
* FirstName * LastName * Age --
It is good to mention that, the GetProperties()
method retrieves only the public and inherited properties. That said, let’s create a User
class with two properties to check how to get the list of properties from a child class:
public sealed class User : Person { public string Email { get; set; } = default!; private string Password { get; set; } = default!; }
This class contains a public Email
and a private Password
property.
Note that this class inherits from the Person
class, so it contains every public/protected person’s property, as well as the Email
, Password
properties.
Now, we can call the RetrieveProperties()
method with a User
instance:
properties = propertiesRetriever.RetrieveProperties(new User());
Which gives us a list of properties:
* Email * FirstName * LastName * Age --
Basically, this method returns every public property from the instance object (User
) and the parent (Person
) class, but it excludes the Password
property because it is marked as private.
To work around this problem, the GetProperties()
method contains an overloaded method with a parameter (BindingFlags
enumeration) to change its behavior depending on this parameter.
Let’s check how it works.
The GetProperties() Method Overload
Let’s create a RetrievePropertiesWithFilter()
method to use this overload:
public PropertyInfo[] RetrievePropertiesWithFilter(object obj, BindingFlags binding) { var type = obj.GetType(); return type.GetProperties(binding); }
This method is very similar to the previous RetrieveProperties()
method, but this time, we receive a BindingFlags
enumeration as a parameter and we send this parameter to the GetProperties()
method.
Now, let’s call the RetrievePropertiesWithFilter()
method to get only the public properties:
properties = propertiesRetriever.RetrievePropertiesWithFilter(new User(), BindingFlags.Instance | BindingFlags.Public);
Note that we can combine two flags using bitwise OR (|
) operator to specify multiple options.
The BindingFlags.Instance
parameter states that we want to include only instance members in the search. The second combined parameter (BindingFlags.Public
) includes the public members in the search.
Let’s check its result:
* Email * FirstName * LastName * Age --
Get the List of Non-public Properties
If we don’t specify any BindingFlag
to bring the private/protected properties, it excludes the Password
property from the list.
Let’s include BindingFlags.NonPublic
enum in the RetrievePropertiesWithFilter()
method’s call:
properties = propertiesRetriever.RetrievePropertiesWithFilter(new User(), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
This time, the GetProperties()
method is going to return every instance member which is public or non-public:
* Email * Password * FirstName * LastName * Age --
Get the List of Properties of a Child Class
To exclude members that are not declared directly on the User
class itself, we can include the BindingFlags.DeclaredOnly
parameter:
properties = propertiesRetriever.RetrievePropertiesWithFilter(new User(), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
This time, the result will only include members that are declared at the level of the User
class hierarchy and exclude any members that are inherited from a base type:
* Email * Password --
Retrieve Base Class Members Only
If we want to retrieve only the base class members, we are going to create a new RetrieveParentClassPropertiesWithFilter()
method with a tiny difference:
public PropertyInfo[] RetrieveParentClassPropertiesWithFilter(object obj, BindingFlags binding) { var type = obj.GetType(); return type.BaseType?.GetProperties(binding); }
We need to add the BaseType
property before the GetProperties()
method call. This way, the GetProperties()
method is going to retrieve only properties from the base class.
Let’s see this in action:
properties = propertiesRetriever.RetrieveParentClassPropertiesWithFilter(new User(), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
This time, we call the RetrieveParentClassPropertiesWithFilter()
method, which will only return the base class properties:
* FirstName * LastName * Age --
As we expected, we have only the properties from the Person
(base) class.
The User
and the Person
class contains only instance (non-static) members. For that reason, if we omit the BindingFlags.Instance
we will have an empty PropertyInfo
array as a result. Let’s see how to retrieve static class members next.
Retrieve Static Members
To start, let’s create a Configuration
class:
public class Configuration { public static string StaticProperty { get; set; } = default!; public string NonStaticProperty { get; set; } = default!; }
Here, we create static and non-static properties, StaticProperty
and NonStaticProperty
respectively.
Let’s call the RetrievePropertiesWithFilter()
method passing a Configuration
instance as a parameter:
properties = propertiesRetriever.RetrievePropertiesWithFilter(new Configuration(), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
Note that we use BindingFlags.Instance
, BindingFlags.Static
and BindingFlags.Public
filters. Once our class contains static and non-static properties and all of them are public, it is necessary to use the three BindingFlags
to retrieve every property.
Let’s check the result:
* StaticProperty * NonStaticProperty --
As expected, we have every property member from the Configuration
class.
Now, let’s omit the BindingFlags.Instance
:
properties = propertiesRetriever.RetrievePropertiesWithFilter(new Configuration(), BindingFlags.Static | BindingFlags.Public);
This time, we send just the BindingFlags.Static
and BindingFlags.Public
:
* StaticProperty --
As expected, we have only the StaticProperty
, as it is static and public.
Conclusion
In this article, we have learned numerous techniques for working with properties in C#. First, we explored how to get the list of properties from a class object. Then, we learned that we can use the BindingFlags to filter our search to match specific criteria. Finally, we have seen that it is possible to retrieve only the parent class members, however, it is necessary a tiny modification to our code.