views:

119

answers:

2

I have seen the reverse of this question quite a few times, but have not seen how to do what I would like.

Suppose I have the following code:

var myNewData = from t in someOtherData
            select new
            { 
                fieldName = t.Whatever,
                fieldName2 = t.SomeOtherWhatever
            };

If I wish to data bind to this class, my column definition would have to include hard-coded strings like "fieldName" and "fieldName2".

Is there any way to call reflection or something else so that I can do something equivelent to the code below (I know the code below is not valid, but am looking for a valid solution).

string columnName = GetPropertyName(myNewData[0].fieldName);

My goal is that if the variable name changes on the anonymous class, a compile-time error would come up until all references were fixed, unlike the current data binding which relies on strings that are not checked until runtime.

Any help would be appreciated.

+2  A: 

You get your property names like this:

using System.Reflection;    

var myNewData = from t in someOtherData
        select new
        { 
            fieldName = t.Whatever,
            fieldName2 = t.SomeOtherWhatever
        };


foreach (PropertyInfo pinfo in myNewData.FirstOrDefault()
                               .GetType().GetProperties()) 
{ 
    string name = pinfo.Name; 
}

// or if you need all strings in a list just use:
List<string> propertyNames = myNewData.FirstOrDefault()
             .GetType().GetProperties().Select(x => x.Name).ToList();
Philip Daubmeier
This doesn't really answer the question.
LukeH
I think it does, the OP wanted to know how to do something similar to the line of code he posted, that is: getting the names of the properties of the anonymous type as strings. He could then check the list of strings against another list of strings, that is hard-coded, to be sure the anonymous type has the right set of properties he is trying to access later on.
Philip Daubmeier
My interpretation is that the OP wants to be able to pass a particular property into a `GetPropertyName` method and have that property's name returned as a string.
LukeH
Ah ok, that makes sense. Then your answer is the way to go.
Philip Daubmeier
+4  A: 
string columnName = GetPropertyName(() => myNewData[0].fieldName);

// ...

public static string GetPropertyName<T>(Expression<Func<T>> expr)
{
    // error checking etc removed for brevity

    MemberExpression body = (MemberExpression)expr.Body;
    return body.Member.Name;
}
LukeH
This is exactly what I was looking for. Thanks.
gwerner
+1 Clever approach! When I thought about passing the field to a method, just the reference to the value is passed, so you have no chance to ever find out the name of the passed field. But passing an expression tree via lambda solves that problem. Cool solution :)
Philip Daubmeier