Question
I am trying to implement a data transformation approach similar to a reflection-based example in my code.
I currently have a GetSourceValue function that uses a switch statement to compare different types and properties. I want to remove those hard-coded types and property checks, and instead have GetSourceValue retrieve the value of a property using only a single string parameter.
The idea is to pass something like a class name and property name in a string, then resolve and return the value of that property dynamically.
Is this possible in C# using reflection?
Short Answer
By the end of this page, you will understand how to use reflection in C# to look up a property by name and read its value dynamically. You will also learn the difference between getting a property from an object instance versus from a type name string, how to handle nested property paths, and how to avoid common reflection mistakes.
Concept
Reflection in C# lets your program inspect types, properties, methods, and fields at runtime.
In this question, the core idea is: instead of writing code like this:
switch (propertyName)
{
case "FirstName":
return person.FirstName;
case "Age":
return person.Age;
}
you want to do something more dynamic:
return GetPropertyValue(person, "FirstName");
That is exactly the kind of problem reflection can solve.
Why this matters
Reflection is useful when:
- property names are only known at runtime
- you are building mapping or transformation tools
- you are writing generic utilities
- you want to reduce repetitive
switchoriflogic
The important distinction
There are two related but different problems:
-
Get a property value from an object using a property name string
- Example: given a
Personobject and the string"FirstName", returnperson.FirstName
- Example: given a
-
Get a type and property from strings
- Example: given
"MyApp.Models.Person"and"FirstName", locate the type and then read the property value from an instance
- Example: given
The first is common and practical. The second is possible too, but you still usually need an actual object instance to read a non-static property value.
Key rule
Reflection can find a property from a string, but:
- for instance properties, you need an object instance
- for static properties, you can read the value without an instance
So if you want to pass "Person.FirstName", reflection can identify the property, but it cannot magically know which Person object you mean unless you also provide the object instance.
Mental Model
Think of an object as a cabinet, and its properties as labeled drawers.
Normally, in C#, you open a drawer directly:
person.FirstName
That means you already know the drawer name at compile time.
Reflection is like saying:
“I have the cabinet, and I have the drawer label as text. Please find that drawer and open it.”
If you only have the text "FirstName", reflection can search the cabinet for a drawer with that label.
If you only have "Person.FirstName", that tells you the kind of cabinet and the drawer name, but not which exact cabinet instance you should open. That is why instance properties still require an object.
Syntax and Examples
Basic syntax
To get a property value by name from an object:
using System;
using System.Reflection;
public static object? GetPropertyValue(object source, string propertyName)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (string.IsNullOrWhiteSpace(propertyName)) throw new ArgumentException("Property name is required.", nameof(propertyName));
PropertyInfo? property = source.GetType().GetProperty(propertyName);
if (property == null)
throw new ArgumentException($"Property '{propertyName}' was not found on type '{source.GetType().Name}'.");
return property.GetValue(source);
}
Example
using System;
public class Person
{
public string FirstName { get; set; } = "Alice";
public int Age { get; set; } = 30;
}
public class Program
{
public static object? GetPropertyValue(object source, string propertyName)
{
var property = source.GetType().GetProperty(propertyName);
return property?.GetValue(source);
}
public static void Main()
{
Person person = new Person();
Console.WriteLine(GetPropertyValue(person, "FirstName"));
Console.WriteLine(GetPropertyValue(person, "Age"));
}
}
Output:
Alice
30
Using a full type name string
If you also have a type name as a string:
using System;
using System.Reflection;
public static object? GetStaticPropertyValue(string typeName, string propertyName)
{
Type? type = Type.GetType(typeName);
if (type == null)
throw new ArgumentException($"Type '{typeName}' was not found.");
PropertyInfo? property = type.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Static);
if (property == null)
throw new ArgumentException($"Static property '{propertyName}' was not found on type '{type.Name}'.");
return property.GetValue(null);
}
This only works directly for static properties. For normal instance properties, you still need an object.
Nested property paths
Sometimes you want a path like "Address.City".
using System;
using System.Reflection;
public static object? GetNestedPropertyValue(object source, string propertyPath)
{
object? current = source;
foreach (string part in propertyPath.Split('.'))
{
if (current == null) return null;
PropertyInfo? property = current.GetType().GetProperty(part);
if (property == null)
throw new ArgumentException($"Property '{part}' was not found on type '{current.GetType().Name}'.");
current = property.GetValue(current);
}
return current;
}
Example:
public class Address
{
public string City { get; set; } = "London";
}
public class Person
{
public string FirstName { get; set; } = "Alice";
public Address Address { get; set; } = new Address();
}
Person person = new Person();
Console.WriteLine(GetNestedPropertyValue(person, "Address.City"));
Output:
London
Why this is useful
This lets you write reusable code for:
- object mapping
- export tools
- generic reporting
- data transformation pipelines
Step by Step Execution
Consider this code:
public class Person
{
public string FirstName { get; set; } = "Alice";
}
Person person = new Person();
object? value = GetPropertyValue(person, "FirstName");
Console.WriteLine(value);
And this method:
public static object? GetPropertyValue(object source, string propertyName)
{
PropertyInfo? property = source.GetType().GetProperty(propertyName);
return property?.GetValue(source);
}
What happens step by step
personis created as an instance ofPerson.GetPropertyValue(person, "FirstName")is called.source.GetType()returns the runtime type:Person..GetProperty("FirstName")searches thePersontype for a public property namedFirstName.- Reflection returns a
PropertyInfoobject representing that property. property.GetValue(source)reads the value ofFirstNamefrom thepersonobject.- The method returns
"Alice"as anobject. Console.WriteLine(value)printsAlice.
Trace example with nested properties
Person person = new Person
{
FirstName = "Alice",
Address = new Address { City = "Paris" }
};
object? value = GetNestedPropertyValue(person, "Address.City");
Execution flow:
- Start with
current = person - Split
"Address.City"into"Address"and"City" - Find property
AddressonPerson - Read
person.Address - Now
currentbecomes theAddressobject - Find property
CityonAddress - Read
address.City - Return
"Paris"
This is how reflection can walk through an object structure dynamically.
Real World Use Cases
Data transformation and mapping
If you are converting one object into another, reflection can read source properties based on configuration strings.
Example:
- source field:
"Customer.Name" - destination field:
"ClientName"
CSV or Excel export tools
A report generator can accept a list of property names and extract values without hard-coded access.
Example:
var columns = new[] { "FirstName", "Age" };
Admin dashboards
Generic UI components often display selected object properties dynamically.
Rule engines and configuration-driven systems
A config file may specify which property to inspect:
Order.TotalUser.EmailProduct.Price
Logging and auditing
Reflection can help collect certain values from objects for diagnostics or change tracking.
API response shaping
Some systems return only fields requested by the client. Reflection can be used to extract those properties, though this should be done carefully for performance and security.
Real Codebase Usage
In real projects, developers often use reflection in controlled utility methods, not scattered everywhere.
Common pattern: reusable helper
public static object? GetPropertyValue(object source, string propertyName)
{
if (source == null) return null;
var property = source.GetType().GetProperty(propertyName);
return property?.GetValue(source);
}
This keeps reflection logic in one place.
Guard clauses
Developers usually validate inputs early:
- null object
- empty property name
- property not found
- wrong casing
Configuration-driven mapping
A common pattern is storing property paths in configuration:
var mappings = new Dictionary<string, string>
{
["CustomerName"] = "Customer.Name",
["CustomerCity"] = "Customer.Address.City"
};
Then a mapper reads each path dynamically.
Error handling
Reflection code often fails at runtime if the property name is wrong. Real code usually:
- throws clear exceptions
- logs invalid property paths
- returns
nullwhen appropriate - validates mappings at startup
Caching reflection metadata
Reflection is slower than direct property access. In real codebases, developers may cache PropertyInfo objects if the same properties are read repeatedly.
Safer alternatives when possible
If the set of properties is known, developers often prefer:
- normal property access
- delegates
- expressions
- mapping libraries
Reflection is usually chosen when flexibility is more important than compile-time safety.
Common Mistakes
1. Forgetting that instance properties need an object
Broken idea:
Type type = Type.GetType("MyApp.Person");
var property = type.GetProperty("FirstName");
var value = property.GetValue(null);
This fails for a normal instance property because null is only valid for static properties.
Fix:
Person person = new Person { FirstName = "Alice" };
var value = person.GetType().GetProperty("FirstName")?.GetValue(person);
2. Assuming Type.GetType always finds your class
Broken code:
Type type = Type.GetType("Person");
This often returns null unless the fully qualified type name is available.
Fix:
- use the full namespace-qualified name
- or use
someObject.GetType()when you already have an instance
3. Not checking for missing properties
Broken code:
var property = source.GetType().GetProperty(propertyName);
return property.GetValue(source);
If the property does not exist, this throws a NullReferenceException.
Fix:
var property = source.GetType().GetProperty(propertyName);
if (property == null)
throw new ArgumentException($"Property '{propertyName}' not found.");
return property.GetValue(source);
4. Ignoring case sensitivity
GetProperty("firstname") will not match FirstName by default.
Possible fix:
var property = source.GetType().GetProperty(
propertyName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
Use this only if case-insensitive matching is acceptable.
5. Forgetting about null in nested paths
Broken code:
GetNestedPropertyValue(person, "Address.City")
If person.Address is null, the next lookup fails.
Fix:
- return
nullwhen an intermediate object isnull - or throw a clear exception
6. Overusing reflection
Reflection is powerful, but direct property access is:
- faster
- easier to read
- compile-time checked
Use reflection when you truly need runtime flexibility.
Comparisons
Reflection vs hard-coded property access
| Approach | Example | Pros | Cons |
|---|---|---|---|
| Hard-coded access | person.FirstName | Fast, safe, easy to refactor | Not dynamic |
| Reflection | GetPropertyValue(person, "FirstName") | Flexible, config-driven | Slower, runtime errors possible |
Reflection vs switch statement
| Approach | Best when | Pros | Cons |
|---|---|---|---|
switch | small fixed list of properties | simple, explicit | repetitive, harder to extend |
| Reflection | property names come from config or input | generic, reusable | less compile-time safety |
Instance property vs static property
| Property type | Needs object instance? | Example access |
|---|---|---|
| Instance property | Yes | property.GetValue(person) |
| Static property | No | property.GetValue(null) |
Reflection vs expressions/delegates
| Approach | Pros | Cons |
|---|---|---|
| Reflection | Works from strings | weaker typing |
| Delegate / lambda | fast and type-safe | cannot be built from a plain property string without extra work |
If you already know the property at compile time, a lambda is usually better. If the property name is only known at runtime, reflection is often the simplest option.
Cheat Sheet
Quick reference
Get property from object by name
var property = source.GetType().GetProperty("FirstName");
var value = property?.GetValue(source);
Safe helper
public static object? GetPropertyValue(object source, string propertyName)
{
if (source == null) throw new ArgumentNullException(nameof(source));
var property = source.GetType().GetProperty(propertyName);
if (property == null)
throw new ArgumentException($"Property '{propertyName}' not found.");
return property.GetValue(source);
}
Case-insensitive lookup
var property = source.GetType().GetProperty(
propertyName,
BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
Nested property path
"Address.City"
Loop through each part and call GetProperty() repeatedly.
Static property lookup
var property = type.GetProperty("SomeStaticProperty", BindingFlags.Public | BindingFlags.Static);
var value = property?.GetValue(null);
Important rules
- Instance properties require an object instance.
- Static properties can use
nullinGetValue. GetProperty()may returnnull.- Reflection errors happen at runtime, not compile time.
- Reflection is slower than direct access.
Common edge cases
- wrong property name
- wrong letter casing
nullintermediate object in nested pathsType.GetType()returningnull- non-public properties needing extra binding flags
FAQ
Can I get a property value from just a string in C#?
Yes, if the string is the property name and you also have the object instance. Reflection can then find and read that property.
Can I pass "ClassName.PropertyName" and get the value directly?
Only if you can also identify the object instance for that class, unless the property is static.
Why does Type.GetType() return null?
Usually because the type name is incomplete. You often need the fully qualified type name, including namespace.
Does reflection work with private properties?
Yes, but you need different binding flags. For most beginner use cases, public properties are simpler and safer.
Is reflection slow?
It is slower than direct property access, but often acceptable for occasional lookups. For heavy repeated use, consider caching.
How do I read nested properties like Address.City?
Split the string by . and resolve each property one step at a time.
What should I return if the property does not exist?
That depends on your design. Common options are returning null, throwing an exception, or logging an error.
Should I replace all switch statements with reflection?
No. Reflection is best when property names are dynamic. If the set of cases is fixed and small, a switch is often clearer.
Mini Project
Description
Build a small reflection-based property reader for a data export tool. Imagine you have objects such as Person and want to export selected fields based on configuration strings like "FirstName" or "Address.City". This project demonstrates how to dynamically resolve property paths instead of hard-coding every property access.
Goal
Create a utility that reads both simple and nested property values from an object using a string path.
Requirements
- Create a
Personclass with at leastFirstName,Age, andAddressproperties. - Create an
Addressclass with at least aCityproperty. - Write a method that accepts an object and a property path string such as
"FirstName"or"Address.City". - Return the correct property value using reflection.
- Handle missing properties with a clear exception or a
nullresult.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
Best Way to Repeat a Character in C#: Building Repeated Strings Efficiently
Learn the best way to repeat a character in C#, compare StringBuilder, string concatenation, and simpler built-in options.
C# Access Modifiers and static: public, private, protected, and Defaults
Learn how C# public, private, protected, and default access control visibility, and how static differs from instance members.