87
votes

I want to get the PropertyInfo for a specific property. I could use:

foreach(PropertyInfo p in typeof(MyObject).GetProperties())
{
    if ( p.Name == "MyProperty") { return p }
}

But there must be a way to do something similar to

typeof(MyProperty) as PropertyInfo

Is there? Or am I stuck doing a type-unsafe string comparison?

Cheers.

4

4 Answers

137
votes

There is a .NET 3.5 way with lambdas/Expression that doesn't use strings...

using System;
using System.Linq.Expressions;
using System.Reflection;

class Foo
{
    public string Bar { get; set; }
}
static class Program
{
    static void Main()
    {
        PropertyInfo prop = PropertyHelper<Foo>.GetProperty(x => x.Bar);
    }
}
public static class PropertyHelper<T>
{
    public static PropertyInfo GetProperty<TValue>(
        Expression<Func<T, TValue>> selector)
    {
        Expression body = selector;
        if (body is LambdaExpression)
        {
            body = ((LambdaExpression)body).Body;
        }
        switch (body.NodeType)
        {
            case ExpressionType.MemberAccess:
                return (PropertyInfo)((MemberExpression)body).Member;
            default:
                throw new InvalidOperationException();
        }
    }
}
68
votes

You can use the new nameof() operator that is part of C# 6 and available in Visual Studio 2015. More info here.

For your example you would use:

PropertyInfo result = typeof(MyObject).GetProperty(nameof(MyObject.MyProperty));

The compiler will convert nameof(MyObject.MyProperty) to the string "MyProperty" but you gain the benefit of being able to refactor the property name without having to remember to change the string because Visual Studio, ReSharper, and the like know how to refactor nameof() values.

13
votes

You can do this:

typeof(MyObject).GetProperty("MyProperty")

However, since C# doesn't have a "symbol" type, there's nothing that will help you avoid using string. Why do you call this type-unsafe, by the way?

1
votes

Reflection is used for runtime type evaluation. So your string constants cannot be verified at compile time.