How to use reflection to get properties in C#

By FoxLearn 2/4/2025 4:04:24 AM   164
In C#, you can use reflection to inspect the properties of a class at runtime. Reflection allows you to obtain metadata about types, methods, properties, fields, etc., without knowing them at compile-time.

You can retrieve the properties of a type using reflection, as shown in this example:

foreach(var propertyInfo in typeof(Book).GetProperties())
{
    Console.WriteLine(propertyInfo.Name);
}

If you are working with an object instance, you can use book.GetType().GetProperties() instead.

The output will display the following properties:

Id
Title
Author
PublishedDate
Price

When GetProperties() is called, it returns a collection of PropertyInfo objects, which give you access to property definitions, such as their name, type, and other metadata. You can also use them to retrieve or modify property values.

Get and Modify Property Values

You can use PropertyInfo.GetValue() and PropertyInfo.SetValue() to access and change the values of properties.

Let's demonstrate with an example using the Book object:

var book = new Book()
{
    Id = 1,
    Title = "The Catcher in the Rye",
    Author = "J.D. Salinger",
    PublishedDate = DateTime.Parse("1951/07/16"),
    Price = 15.99m
};

Get Property Values

To retrieve the values of all properties, use PropertyInfo.GetValue():

foreach (var propertyInfo in book.GetType().GetProperties())
{
    var propertyName = propertyInfo.Name;
    var propertyValue = propertyInfo.GetValue(book);
    Console.WriteLine($"{propertyName}={propertyValue}");
}

The output will be:

Id=1
Title=The Catcher in the Rye
Author=J.D. Salinger
PublishedDate=7/16/1951 12:00:00 AM
Price=15.99

Modify Property Values

To change the value of a property, use PropertyInfo.SetValue():

var authorProperty = book.GetType().GetProperty("Author");
authorProperty.SetValue(book, "J.D. Salinger Updated");

Console.WriteLine(book.Author);

The updated value will be:

J.D. Salinger Updated

Potential Issues to Watch For

Set the Right Type

If you attempt to assign a value of the wrong type, such as trying to set a string value to an int property, you’ll encounter an exception.

For example:

string id = "1";
var idProp = book.GetType().GetProperty("Id");
idProp.SetValue(book, id); // Throws an exception

This results in an ArgumentException because a string can't be converted to an int.

To prevent this, convert the value to the correct type before assigning it:

string id = "2";
var idProp = book.GetType().GetProperty("Id");
var idWithCorrectType = Convert.ChangeType(id, idProp.PropertyType);
idProp.SetValue(book, idWithCorrectType);

Avoid Modifying a Read-Only Property

If you try to modify a property that doesn’t have a setter, or is read-only, you’ll face issues.

For example:

var priceProp = book.GetType().GetProperty("Price");
priceProp.SetValue(book, 20.99m); // This will fail if the property is read-only.

If the property has a private setter, you may still be able to modify it, depending on the property’s declaration.

Check for Nulls

To avoid NullReferenceException, always check if PropertyInfo is null before using it:

var property = book.GetType().GetProperty("Price");
if (property != null)
{
    var val = property?.GetValue(book);
    // Do something with the value
}

Filtering Properties by Definition

Get a Specific Property by Name

If you're only interested in a specific property, use GetProperty() instead of GetProperties():

var property = book.GetType().GetProperty("PublishedDate");
Console.WriteLine(property.GetValue(book));

Get All Private Properties

To access private properties, use the appropriate BindingFlags:

foreach (var propertyInfo in book.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance))
{
    Console.WriteLine(propertyInfo.Name);
}

Get All Properties of a Specific Type

If you want to filter properties based on their type, for example, all DateTime properties, you can do this:

foreach (var propertyInfo in book.GetType().GetProperties().Where(p => p.PropertyType == typeof(DateTime)))
{
    Console.WriteLine($"{propertyInfo.Name}={propertyInfo.GetValue(book)}");
}

Get Properties that Have a Setter

To exclude properties that are read-only (i.e., without a setter), filter based on SetMethod:

foreach (var propertyInfo in book.GetType().GetProperties().Where(p => p.SetMethod != null))
{
    Console.WriteLine($"{propertyInfo.Name}={propertyInfo.GetValue(book)}");
}

This will print only properties that have a setter.

Get Properties That Have an Attribute

You can also filter properties based on custom attributes. For example, let’s assume we have a Required attribute applied to some properties:

using System.ComponentModel.DataAnnotations;

[Required]
public int Id { get; set; }

[Required]
public string Title { get; set; }

You can filter properties with the Required attribute like this:

foreach (var propertyInfo in book.GetType().GetProperties()
    .Where(p => p.GetCustomAttribute<RequiredAttribute>() != null))
{
    Console.WriteLine($"{propertyInfo.Name} is required.");
}

This will output:

Id is required.
Title is required.

These examples cover various ways to interact with properties using reflection.