views:

69

answers:

3

Give a class like below, how can i find the name of one particluar property?

public class Student
{
    public int Grade
    {
        get;
        set;
    }

    public string TheNameOfTheGradeProperty
    {
        get
        {
            return ????
        }
    }

    // More properties..    
}

So i would like to return the string "Grade" from the TheNameOfTheGradeProperty property. The reason i'm asking is that i do not want to use a hardcoded string, but rather a lambda expression or something else.

How can i acheive this?

+1  A: 
using System.Reflection;

return typeof(Student).GetProperty("Grade").Name;

But as you can see, you're not that far ahead using reflection (in this manner) because the "Grade" string is still hard-coded which means in this scenario it's more efficient just to return "Grade".


One thing I like to do is create and add a custom attribute to a member like so. The following prevents you from having to use the hard-coded string "Grade".

public class Student {

// TAG MEMBER WITH CUSTOM ATTRIBUTE
[GradeAttribute()]
public int Grade
{
    get;
    set;
}

public string TheNameOfTheGradeProperty
{
    get
    {
        /* Use Reflection.
           Loop over properties of this class and return the
           name of the one that is tagged with the 
           custom attribute of type GradeAttribute.
        */
    }
}

// More properties..    

} 

Creating custom attributes can be found here.

John K
I cannot stop grinning at this answer.
johnc
@johnc: It's old fashioned, pales considering the 3.x features, and is likely bad usage of an attribute but it's an option nonetheless. Not a "proudest moment" though :)
John K
@jdk Nothing wrong with the code, I'm just amused at the wonderful obfuscation of a simple return "Grade";. I'm sure there's a requirement he has, I just don't know what it is at the moment
johnc
+1  A: 

You have a very strange request. Are you saying you want to not use a hard-coded string because you want TheNameOfTheGradeProperty to stay up to date if you refactor the class? If so, here's a strange way to do so:

public class Student
{
    public int Grade { get; set; }

    public string TheNameOfTheGradeProperty
    {
        get
        {
            Expression<Func<int>> gradeExpr = () => this.Grade;
            MemberExpression body = gradeExpr.Body as MemberExpression;
            return body.Member.Name;
        }
    }
}
Jacob
+1 for qualifying strange request with strange answer
John K
+2  A: 

It is possible to use an expression to find the name of the property, using a simple extension method you can use it on any object... if you need to restrict it to a set of objects you can apply a generic constraint on T. Hope this helps

public class Student
{
    public int Grade { get; set;}
    public string Name { get; set; }

    public string GradePropertyName
    {
        get { return this.PropertyName(s => s.Grade); }
    }

    public string NamePropertyName
    {
        get { return this.PropertyName(s => s.Name); }
    }
}

public static class Helper
{
    public static string PropertyName<T, TProperty>(this T instance, Expression<Func<T, TProperty>> expression)
    {
        var property = expression.Body as MemberExpression;

        if (property != null)
        {
            var info = property.Member as PropertyInfo;
            if (info != null)
            {
                return info.Name;
            }
        }

        throw new ArgumentException("Expression is not a property");
    }
}
Rohan West
Better than mine. Voted.
Ben M