9

Lets say I have

class Person
{
    public Person(int age, string name)
    {
        Age = age;
        Name = name; 
    }
    public int Age{get;set}
    public string Name{get;set}
}

and I would like to create a method that accepts a string that contains either "age" or "name" and returns an object with the value of that property.

Like the following pseudo code:

    public object GetVal(string propName)
    {
        return <propName>.value;  
    }

How can I do this using reflection?

I am coding using asp.net 3.5, c# 3.5

TheMoot
  • 2,903
  • 4
  • 26
  • 27
  • 3
    Ask yourself whether strongly typed access is the better option. Most of the time this is the case. – ChaosPandion Jun 21 '11 at 19:37
  • 1
    Bear in mind that the class you've shown doesn't *have* any properties. It has two fields. There's a big difference between fields and properties - which are you actually interested in? – Jon Skeet Jun 21 '11 at 19:38
  • @ChaosPandion:What do you mean by strongly typed access? switch (propname){} ? – TheMoot Jun 21 '11 at 19:40
  • @jon - Actually properties. Let me edit my question. – TheMoot Jun 21 '11 at 19:41
  • @TheMoot - Keep in mind that my advice is very general as I don't know the logic of your program. It could potentially mean a full rewrite of existing logic which in many cases will be unfeasible. – ChaosPandion Jun 21 '11 at 19:46
  • @TheMoot - strongly typed access means avoiding the use of "magic strings" to get property values. In other words, using the properties directly rather than adding a layer of indirection. (This may or may not be feasible for your application). – Ryan Emerle Jun 21 '11 at 19:49
  • possible duplicate of [Get property value from string using reflection in C#](http://stackoverflow.com/questions/1196991/get-property-value-from-string-using-reflection-in-c-sharp) – nawfal Apr 27 '13 at 15:24

4 Answers4

15

I think this is the proper syntax...

var myPropInfo = myType.GetProperty("MyProperty");
var myValue = myPropInfo.GetValue(myInstance, null);
Todd
  • 1,461
  • 2
  • 13
  • 27
  • I don't have edit privileges , but your second line var myValue = propertyInfo.GetValue(myInstance, null); should say myproperty.Info etc. And thanks, then it worked. – TheMoot Jun 21 '11 at 20:00
4

First of all, the example you provided has no Properties. It has private member variables. For properties, you would have something like:

public class Person
{
    public int Age { get; private set; }
    public string Name { get; private set; }

    public Person(int age, string name)
    {
        Age = age;
        Name = name;
    }
}

And then using reflection to get the values:

 public object GetVal(string propName)
 {
     var type = this.GetType();
     var propInfo = type.GetProperty(propName, BindingFlags.Instance);
     if(propInfo == null)
         throw new ArgumentException(String.Format(
             "{0} is not a valid property of type: {1}",
             propName, 
             type.FullName));

     return propInfo.GetValue(this);
 }

Keep in mind, though, that since you would already have access to the class and its properties (because you also have access to the method), it's much easier just to use the properties rather than do something fancy via Reflection.

Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
  • sorry, jon pointed this out. I edited my example. I had dummied down this example a little bit too far. – TheMoot Jun 21 '11 at 19:44
  • The sample code assumes that a missing property and a property having the value `null` are equivalent. You may want to throw an `ArgumentException` if the given `propName` does not map to a property. – Ryan Emerle Jun 21 '11 at 19:52
2

You can do something like this:

Person p = new Person( 10, "test" );

IEnumerable<FieldInfo> fields = typeof( Person ).GetFields( BindingFlags.NonPublic | BindingFlags.Instance );

string name = ( string ) fields.Single( f => f.Name.Equals( "name" ) ).GetValue( p );
int age = ( int ) fields.Single( f => f.Name.Equals( "age" ) ).GetValue( p );

Keep in mind since these are private instance fields you need to explicitly state the binding flags in order to get them via reflection.

Edit:

It seems you changed your sample from using fields to properties, so I'm just going to leave this here in case you change back again. :)

Brandon Moretz
  • 7,512
  • 3
  • 33
  • 43
  • I edited my example becuase I had dummied down a little bit too far. But your answer may come in useful for fields so thanks, and I will vote you up. – TheMoot Jun 21 '11 at 19:53
0

ClassInstance.GetType.GetProperties() will get you your list of PropertyInfo objects. Spin through the PropertyInfos checking PropertyInfo.Name against propName. If they're equal then call the GetValue method of the PropertyInfo class to get its value.

http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.aspx

NoAlias
  • 9,218
  • 2
  • 27
  • 46