In programming, there are scenarios where dynamically retrieving the value of a property by its name becomes necessary. This guide delves into the intricacies of how to get the value of a property by using its name in C# using reflection. Assuming we have a foundational understanding of C# and reflection, we’ll skip exhaustive explanations of basic concepts. We will set up a simple console application to demonstrate this useful capability in C#.
Let’s dive in.
Retrieve Property Value By Name
To start, let’s consider a simple Person
class:
public class Person { private Guid _id = Guid.NewGuid(); public string FirstName { get; set; } = string.Empty; public string LastName { get; set; } = string.Empty; public int Age { get; set; } = 0; public bool IsDeleted { get; set; } }
We define a Person
class with public fields and a single private field. We aim to retrieve property values from an instance of this class dynamically.
To retrieve the value of a public property by its name, let’s create a utility method:
public static bool TryGetPropertyValue<TType, TObj>(TObj obj, string propertyName, out TType? value) { value = default; if (obj is null) { Console.WriteLine("Object is null."); return false; } PropertyInfo? propertyInfo = typeof(TObj).GetProperty(propertyName); if (propertyInfo is null) { Console.WriteLine($"Property '{propertyName}' not found."); return false; } object? propertyValue = propertyInfo.GetValue(obj); if (propertyValue is null && Nullable.GetUnderlyingType(typeof(TType)) is not null) { return true; } if (propertyValue is not TType typedValue) { Console.WriteLine($"Property '{propertyName}' is of type {propertyInfo.PropertyType}, got {typeof(TType)}."); return false; } value = typedValue; return true; }
To start with, we define a generic utility method, which means it can return properties of any type. Initially, the method checks if the provided obj
object is null. This step is crucial to avoid a NullReferenceException
. After ensuring the object is not null, we attempt to retrieve the public property information using reflection with the GetProperty()
method. If the property doesn’t exist, we promptly inform the caller and exit gracefully.
Furthermore, it’s important to ensure that the property’s type matches the expected type TType
. We achieve this using the is not
operator, which checks if the property value can be cast to type TType
.
In addition, if the property value is null and the expected type TType
is nullable, we handle this scenario correctly. In such a way we ensure that we gracefully manage null values. Finally, if all checks pass, the property value is cast to type TType
and assigned to the output parameter, thereby completing the process.
Finally, to test this out, let’s create an instance of the type Person
and use our utility method to retrieve the value of Age
property:
Person person = new() { FirstName = "Kevin", LastName = "Otim", Age = 18, IsDeleted = false, }; PropertyRetrieval.TryGetPropertyValue<int, Person>(person, "Age", out var value); Console.WriteLine($"Retrieved value: {value}.");
We pass the person
object and Age
string as the property name and we log the result to the console.
Upon inspecting the console, we will observe:
Retrieved value: 18.
Please note, that the provided TryGetPropertyValue()
the method only works for public instance properties retrieval. So, instance and static private properties and protected properties will not be found. To make it work with instance and static private properties and protected properties, we can add BindingFlags
to the GetProperty()
method call:
PropertyInfo? propertyInfo = typeof(TObj).GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
Handling Edge Cases
There are cases like property renaming, removal, and changes in type that can pose significant hurdles when trying to retrieve values. We already handled those cases in our method, but let’s just explicitly mention those.
Property Rename or Removal
When we use reflection in C# to access properties, handling scenarios where a property gets renamed or removed is crucial. Let’s consider a situation where we attempt to retrieve a non-existent Address
property using our utility method:
PropertyRetrieval.TryGetPropertyValue<string>(person, "Address", out var value);
When we run the program and inspect the console, we will observe:
Property 'Address' not found.
Changing Property Type
Handling changes in property types is crucial, so, let’s test out our utility method for a case where we try to retrieve a property with a wrong type:
PropertyRetrieval.TryGetPropertyValue<string>(person, "IsDeleted", out var value);
Here we attempt to retrieve the value of IsDeleted
property as a string
type, however, we know IsDeleted
is a boolean.
Upon running the program and inspecting the console, we observe the message:
Property 'IsDeleted' is of type System.Boolean, got System.String.
Conclusion
In this guide, we have explored how to get the value of a property by using its name in C#, furthermore, we used a concise and pragmatic approach, moreover, we have considered edge cases and handled them with finesse.
Remember, reflection comes with performance considerations, and its usage should be reasonable. The provided utility method serves as a tool, ready to tackle dynamic property retrieval challenges.