views:

407

answers:

3

I would like to know how to get the name of the property that a method parameter value came from. The code snippet below shows what I want to do:

Person peep = new Person();
Dictionary<object, string> mapping = new Dictionary<object, string>();
mapping[peep.FirstName] = "Name";
Dictionary<string, string> propertyToStringMapping = Convert(mapping);
if (mapping[peep.FirstName] == propertyToStringMapping["FirstName"])
  Console.WriteLine("This is my desired result");

private Dictionary<string, string> Convert(Dictionary<object, string> mapping)
{
   Dictionary<string, string> stringMapping = new Dictionary<string, string>();
   foreach (KeyValuePair<object, string> kvp in mapping)
   {
     //propertyName should eqal "FirstName"
     string propertyName = kvp.Key??????
     stringMapping[propertyName] = kvp.Value;
   }
   return stringMapping;
}
+1  A: 

You are not able to do so in this way, since the way it works is that C# evaluates the value of FirstName property by calling its get accessor and passes the value of that to the indexer of the dictionary. Therefore, the way you found out FirstName value is completely lost. Just like the way you evaluate 2 + 2. If you write, "x = 2 + 2", x will have the value 4 but there will be no way to tell if it was 3 + 1 or 2 + 2 or 5 + (-1) or ... that evaluated to 4.

Mehrdad Afshari
A: 

I think ultimately you will need to store either the PropertyInfo object associated with the property, or the string representation of the property name in you mapping object. The syntax you have:

mapping[peep.FirstName] = "Name";

Would create an entry in the dictionary with a key value equal to the value of the peep.FirstName property, and the Value equal to "Name".

If you store the property name as a string like:

mapping["FirstName"] = "Name";

You could then use reflection to get the "FirstName" property of your object. You would have to pass the "peep" object into the Convert function, however. This seems to be somewhat opposite of what you are wanting to do.

You may also be able to get crazy with Expressions and do something like:

var mapping = new Dictionary<Expression<Action<T>>,string>();
mapping[ p => p.FirstName ] = "Name";

Then in your Convert function you could examine the expression. It would look something like:

private Dictionary<string,string> Convert(Dictionary<Expression<Action<T>>,string> mapping)
{
    var result = new Dictionary<string,string>();
    foreach(var item in mapping)
    {
        LambdaExpression ex = item.Key as LambdaExpression;
        string propertyName = ((MemberExpression)ex.Body).Member.Name;
        string propertyValue = item.Value;
        result.Add(propertyName,proeprtyValue);
    }
    return result;
}

This is more or less off the top of my head, so I may have the expression types off a bit. If there are issues with this implementation let me know and I will see if I can work out a functional example.

ckramer
A: 

I don't know much about C#, but I suppose peep is an enum? As for Java, you could do:

String propertyName = kvp.key.toString()

Maybe there's something similar in C#?

And even if peep isn't a enum: I see no reason why the key should be an arbitrary object? So maybe the solution is exactly to use an enum as type of the key?

Also, I don't know what you're trying to do but usually, I'd not recommend you to convert the enum key to a string. What can you do with a string what you can't do, too, with an enum?

codethief