45

How do I get the value of a MemberInfo object? .Name returns the name of the variable, but I need the value.

I think you can do this with FieldInfo but I don't have a snippet, if you know how to do this can you provide a snippet??

Thanks!

nawfal
  • 70,104
  • 56
  • 326
  • 368
Keith Fitzgerald
  • 5,651
  • 14
  • 43
  • 58

3 Answers3

50

Although I generally agree with Marc's point about not reflecting fields, there are times when it is needed. If you want to reflect a member and you don't care whether it is a field or a property, you can use this extension method to get the value (if you want the type instead of the value, see nawful's answer to this question):

    public static object GetValue(this MemberInfo memberInfo, object forObject)
    {
        switch (memberInfo.MemberType)
        {
            case MemberTypes.Field:
                return ((FieldInfo)memberInfo).GetValue(forObject);
            case MemberTypes.Property:
                return ((PropertyInfo)memberInfo).GetValue(forObject);
            default:
                throw new NotImplementedException();
        }
    } 
Community
  • 1
  • 1
EJHewy
  • 564
  • 4
  • 7
  • 1
    much better for me than top answer – T.Todua May 09 '18 at 07:34
  • You can also use type switch for this, to simplify ` switch (memberInfo) { case FieldInfo fieldInfo: return fieldInfo.GetValue(forObject); case PropertyInfo propertyInfo: return propertyInfo.GetValue(forObject); default: throw new NotImplementedException(); }` Edit: sorry for ugly formatting – Jannek Mar 20 '19 at 12:40
38

Here's an example for fields, using FieldInfo.GetValue:

using System;
using System.Reflection;

public class Test
{
    // public just for the sake of a short example.
    public int x;

    static void Main()
    {
        FieldInfo field = typeof(Test).GetField("x");
        Test t = new Test();
        t.x = 10;

        Console.WriteLine(field.GetValue(t));
    }
}

Similar code will work for properties using PropertyInfo.GetValue() - although there you also need to pass the values for any parameters to the properties. (There won't be any for "normal" C# properties, but C# indexers count as properties too as far as the framework is concerned.) For methods, you'll need to call Invoke if you want to call the method and use the return value.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    thanks jon - could you give an example starting with a MemberInfo object though? – Keith Fitzgerald Oct 26 '08 at 20:30
  • 2
    Of what kind? MemberInfos can be properties, fields, methods, events or other types. You can't treat them all the same way. What would be the "value" of a nested type, for instance? Perhaps you should tell us more about your problem. – Jon Skeet Oct 26 '08 at 20:34
  • 1
    too bad GetValue/SetValue were not an Interface that could be checked against. –  Sep 05 '10 at 16:17
  • 2
    @user295190, **System.Reflection.BindingFlags** `var propeties = MyObject.GetType().GetProperties(BindingFlags.GetProperty & BindingFlags.SetProperty)` – Brett Caswell Sep 29 '14 at 20:48
  • regarding my now uneditable posted comment.... of course, these are Flag Enumerations that one would use bitwise operators on... – Brett Caswell Sep 29 '14 at 20:56
14

Jon's answer is ideal - just one observation: as part of general design, I would:

  1. generally avoid reflecting against non-public members
  2. avoid having public fields (almost always)

The upshot of these two is that generally you only need to reflect against public properties (you shouldn't be calling methods unless you know what they do; property getters are expected to be idempotent [lazy loading aside]). So for a PropertyInfo this is just prop.GetValue(obj, null);.

Actually, I'm a big fan of System.ComponentModel, so I would be tempted to use:

    foreach(PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
    {
        Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
    }

or for a specific property:

    PropertyDescriptor prop = TypeDescriptor.GetProperties(obj)["SomeProperty"];
    Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));

One advantage of System.ComponentModel is that it will work with abstracted data models, such as how a DataView exposes columns as virtual properties; there are other tricks too (like performance tricks).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • This proved very effective for my scenario as I have to work with properties and calling GetField() on the object kept returning a null. Thanks for this. – Mike Malter Sep 14 '12 at 01:30
  • ah, there it is.. I could only vaguely recall that another means existed outside of the Reflection namespace: `MemberInfo` and `PropertyInfo`.. `PropertyDescriptor` serves my current purpose well as I'm using `INotifyPropertyChanged` in my instance... – Brett Caswell Sep 29 '14 at 20:54