Reflection
Property Value
String Manipulation
Programming
Code Implementation

Get property value from string using reflection

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Reflection lets you inspect types and members at runtime, which is useful when the property name is only known as a string. In C#, the usual pattern is to look up a PropertyInfo, validate it, and then call GetValue on the target object.

The Basic Reflection Flow

The process has three steps:

  1. Get the runtime type.
  2. Find the property by name.
  3. Read the value from an object instance.

Here is the smallest useful example.

csharp
1using System;
2using System.Reflection;
3
4public class Person
5{
6    public string Name { get; set; } = "";
7    public int Age { get; set; }
8}
9
10public static class Program
11{
12    public static void Main()
13    {
14        var person = new Person { Name = "Alice", Age = 30 };
15        string propertyName = "Name";
16
17        PropertyInfo? property = person.GetType().GetProperty(propertyName);
18
19        if (property is null)
20        {
21            Console.WriteLine("Property not found");
22            return;
23        }
24
25        object? value = property.GetValue(person);
26        Console.WriteLine(value);
27    }
28}

This is runnable as-is. If the property exists, the code prints Alice.

Wrapping It in a Reusable Helper

In real projects, you usually want a helper that checks for missing properties and returns a value in one place.

csharp
1using System;
2using System.Reflection;
3
4public static class ReflectionHelper
5{
6    public static object? GetPropertyValue(object target, string propertyName)
7    {
8        if (target is null)
9            throw new ArgumentNullException(nameof(target));
10
11        PropertyInfo? property = target.GetType().GetProperty(propertyName);
12
13        if (property is null)
14            throw new ArgumentException(
15                $"Property '{propertyName}' was not found.",
16                nameof(propertyName));
17
18        return property.GetValue(target);
19    }
20}

This is a better foundation because callers get a clear failure instead of a NullReferenceException later.

Supporting Case-Insensitive Lookup

If the property name comes from user input or external configuration, exact casing may be inconvenient. GetProperty supports binding flags for a case-insensitive lookup.

csharp
1using System;
2using System.Reflection;
3
4public static class ReflectionHelper
5{
6    public static object? GetPropertyValueIgnoreCase(object target, string propertyName)
7    {
8        PropertyInfo? property = target.GetType().GetProperty(
9            propertyName,
10            BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
11
12        if (property is null)
13            throw new ArgumentException($"Property '{propertyName}' was not found.");
14
15        return property.GetValue(target);
16    }
17}

This is convenient, but use it deliberately. If the application contract says the property names are exact, silent case-insensitive lookup may hide bugs.

Nested Properties Need More Than One Lookup

A string like Address.City is not a single property. You need to resolve it segment by segment.

csharp
1using System;
2using System.Reflection;
3
4public static class ReflectionHelper
5{
6    public static object? GetNestedPropertyValue(object target, string path)
7    {
8        object? current = target;
9
10        foreach (string part in path.Split('.'))
11        {
12            if (current is null)
13                return null;
14
15            PropertyInfo? property = current.GetType().GetProperty(part);
16            if (property is null)
17                throw new ArgumentException($"Property '{part}' was not found.");
18
19            current = property.GetValue(current);
20        }
21
22        return current;
23    }
24}

This pattern is common in grid components, serializers, and rule engines where property paths come from configuration.

Reflection Is Flexible, Not Free

Reflection is slower than direct property access and bypasses normal compile-time checking. That does not make it wrong, but it does mean you should keep it at boundaries where flexibility matters:

  • data-binding utilities
  • admin tooling
  • serialization or mapping layers
  • plug-in systems

If the property is known at compile time, direct access is better.

A Generic Alternative

If you know the property at compile time but still want a reusable abstraction, lambda expressions are safer than strings.

csharp
1using System;
2
3public static class Program
4{
5    public static void PrintValue<T, TValue>(T target, Func<T, TValue> selector)
6    {
7        Console.WriteLine(selector(target));
8    }
9
10    public static void Main()
11    {
12        var person = new Person { Name = "Alice", Age = 30 };
13        PrintValue(person, p => p.Name);
14    }
15}
16
17public class Person
18{
19    public string Name { get; set; } = "";
20    public int Age { get; set; }
21}

This avoids misspelled property names completely.

Common Pitfalls

The first pitfall is assuming the property always exists. GetProperty can return null, and production code should treat that as expected input, not as an impossible state.

Another mistake is ignoring non-public or static members. GetProperty without flags only looks for public instance properties. If your target member is not public, the default lookup will not find it.

Developers also forget about indexer properties. A property that expects parameters cannot be read with a simple GetValue(target) call.

Finally, reflection-heavy code often grows into a stringly typed API that is difficult to refactor. Use it where flexibility is necessary, not as a default replacement for normal object access.

Summary

  • In C#, use GetType().GetProperty(name) and GetValue(target) to read a property by string name.
  • Check for missing properties explicitly before reading the value.
  • Use binding flags if you need case-insensitive or non-default lookup behavior.
  • Resolve nested paths one segment at a time.
  • Prefer direct access or lambda expressions when the property is known at compile time.

Course illustration
Course illustration

All Rights Reserved.