3

Say I have a class

public class Employee
{
    public string name = "";
    public int age = 20;
}

now I want a function that can dynamically get the value of a specified member of Employee

public class Util<T>
{
    public static string GetValue(T obj, string member)
    {
        // how to write
    }
}

so that I can use it like

Employee p1 = new Employee();
string a = Util<Employee>.GetValue(p1, "age"); // a should be "20"

How to do it? like access member use obj["???"] in PHP

demaxSH
  • 1,743
  • 2
  • 20
  • 27
  • 2
    I never knew you could use `$obj['property']` in PHP. Did you mean JavaScript? – BoltClock Apr 19 '11 at 13:03
  • That sounds like associative arrays. I thought PHP syntax for dynamic member access was $obj->$var. Are you trying to get values from an anonymous type? If so, it might be easier to try the "Cast by Example" trick. – Mauricio Apr 19 '11 at 13:14
  • something like $_REQUEST["type"] in PHP (well its not a object of a class...), or like actionscript3 – demaxSH Apr 19 '11 at 13:17
  • 1
    While this is possible in C# using reflection (see the answers below), it's unidiomatic and very verbose. I suggest that you solve your problem in a different way. If you need a loosely-typed collection of properties indexed by string, for example, try a `Dictionary`. – JSBձոգչ Apr 19 '11 at 13:18
  • Here is my problem: I have several collections ObserverableCollection , and I need a function to calculate the average age of these kind of collections. since all the class of Employ/Student/Patient has the member of "age", the function will looks like: int ave = GetAverage(students, "age") – demaxSH Apr 19 '11 at 13:51

5 Answers5

4

Reflection. Take a look here:

Reflection: Property Value by Name

Oh, and also here in our very own SO!

Update

Sigh... It's all about "teh codez"... Here you go:

p1.GetType().GetProperty("age").GetValue(p1,null);

But do check the links, there's stuff to learn!

Community
  • 1
  • 1
Adriano Carneiro
  • 57,693
  • 12
  • 90
  • 123
0

While I see a lot of usage of reflection here, maybe in your usecase you can do

object p1 = new Employee();
var employee = p1 as Employee;
// optionally you could do a nullcheck
string a = employee.age; // a should be "20"

Reflection works, but in your case I would just not go that far. but maybe you need generics then yes, go with reflection instead.

Mathijs Segers
  • 6,168
  • 9
  • 51
  • 75
0

yes, it's called Reflection. See Get property value from string using reflection in C#

Community
  • 1
  • 1
Adam Straughan
  • 2,766
  • 3
  • 20
  • 27
0

try following code:

// get value of private field: private double _number
int value = (int)typeof(p1).InvokeMember("age",
BindingFlags.GetField | BindingFlags.Instance | BindingFlags.NonPublic,
null, p1, null);

or

 // Get the FieldInfo of MyClass.
 FieldInfo[] myFields = typeof(p1).GetFields(BindingFlags.Public | BindingFlags.Instance);

 var age = myFields[i].GetValue(p1);

check link for more details

Andrei Andrushkevich
  • 9,905
  • 4
  • 31
  • 42
0

Where does the parameter "age" come from? You should think about other designs where the choice of property isn't stored in a string.

For example, if you want to display a drop-down allowing the user to choose a column to sort by, you would want to pass a Comparer<Employee> from the view to the model, this will be much MUCH faster, and also use the correct numeric sort instead of lexicographic.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Here is my problem: I have several collections ObserverableCollection , and I need a function to calculate the average age of these kind of collections. since all the class of Employ/Student/Patient has the member of "age", the function will looks like: int ave = GetAverage(students, "age") – demaxSH Apr 19 '11 at 13:38
  • @demaxSH: It would be much better to pass a lambda, like `GetAverage(students, s => s.age)`. You can probably even find a function in the LINQ library that will already do the averaging for you. – Ben Voigt Apr 19 '11 at 14:17