0

How can I get field's value if it's defined as automatic property?
I don't know why but first time I encounter such simple task with such an unexplained method called GetValue which don't work as I want to and usually throws all kinds of exceptions instead of doing its original simple job..

Some code for example:

Class A
{
   public int Age { get; set;}
}

Now assume that after reflection I hold A instances' fields in structure of FiledInfo[] .
Now I have found the relevant fieldInfo in the above array and his name is :
{Int32 k__BackingField} sound strange,anyway..
How do I use GetValue() in order to get the int value? As I said I tried many things..

EDIT: (this is partial simplified code - don't get mad)

private static string foo1<T>(T o)
        {
            var type = o.GetType();
            var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
           ....
            foo(fields);
         }
}

private static void foo(FieldInfo[] fields)  
        {

            foreach (FieldInfo field in fields)
            {

                if (field.FieldType.IsValueType)
                {
                    var fieldNameLength = field.Name.IndexOf(">") - (field.Name.IndexOf("<")+1);
                    var fieldName = field.Name.Substring(field.Name.IndexOf("<")+1, fieldNameLength);
                    var fieldValue = field.ReflectedType.GetProperty(fieldName).GetValue(field.ReflectedType, null)
                }
             }
}
JavaSa
  • 5,813
  • 16
  • 71
  • 121
  • 6
    If it's an automatic property, and you're having exceptions thrown while accessing its value via reflection, then you're probably doing something wrong with your reflection code. Post or ask a question on that first before trying to get around it. – Chris Sinclair Dec 14 '12 at 20:43
  • 1
    If you're just interested in the field's value, why don't you retrieve the property value? It's always the same as the field's value for an automatic property. – O. R. Mapper Dec 14 '12 at 20:44
  • okay I'm adding my relevant reflection code as soon as possible – JavaSa Dec 14 '12 at 20:45
  • Please show code you've tried. It is unclear why you can't get value of a field (i.e. you have problem getting auto-generated name, you don't know how to get field altogether, something else...) – Alexei Levenkov Dec 14 '12 at 20:45
  • tried also to get through the property – JavaSa Dec 14 '12 at 20:45
  • code was added this example is for through property, maybe it is easier by field but same problem – JavaSa Dec 14 '12 at 20:54
  • Instead of `var fieldValue = field.ReflectedType.GetProperty(fieldName).GetValue(field.ReflectedType, null)` you should just have: `var fieldValue = field.GetValue(o, null)` Notice you need to pass your instance of `o` in. Really, you should do what L.B posted and find your property by name, or if you don't know the name, enumerate through through them via `myType.GetProperties` – Chris Sinclair Dec 14 '12 at 20:56

2 Answers2

2
A a = new A() { Age = 33 };
var age = a.GetType().GetProperty("Age").GetValue(a);
L.B
  • 114,136
  • 19
  • 178
  • 224
1

Instead of var fieldValue = field.ReflectedType.GetProperty(fieldName).GetValue(field.ReflectedType, null) you should just have: var fieldValue = field.GetValue(o, null) Notice you need to pass your instance of o in. Really, you should do what L.B posted and find your property by name, or if you don't know the name, enumerate through through them via myType.GetProperties

Here's your code modified to work with properties:

private static void foo1<T>(T o)
{
    var type = o.GetType();
    var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);

    foo(properties, o);
}

private static void foo(PropertyInfo[] properties, object o)
{
    foreach (PropertyInfo property in properties)
    {
        if (property.PropertyType.IsValueType)
        {
            var propertyValue = property.GetValue(o, null);
            //do something with the property value?
        }
    }
}

EDIT: You may want to ensure that the property has a getter (see: How do you find only properties that have both a getter and setter?), or maybe that it's an auto-property (see: How to find out if a property is an auto-implemented property with reflection?) but I'm guessing this is not necessarily a requirement for you, probably just the proper usage of the GetValue method or how to use reflection to inspect types.

EDIT: Here's the same code using fields if you still wish to use them:

private static void foo1<T>(T o)
{
    var type = o.GetType();
    var fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);

    foo(fields, o);
}

private static void foo(FieldInfo[] fields, object o)
{
    foreach (FieldInfo field in fields)
    {
        if (field.FieldType.IsValueType)
        {
            var fieldValue = field.GetValue(o);
            //do something with the field value?
        }
    }
}
Community
  • 1
  • 1
Chris Sinclair
  • 22,858
  • 3
  • 52
  • 93
  • Ok ,one question, the Getfield method I used don't already include the properties you search for with your version – JavaSa Dec 14 '12 at 21:07
  • 1
    @JavaSa Technically, but I think you're better off hitting the property instead unless there's some special reason why you want the backing field. Some platforms (e.g., Silverlight) it's impossible for you to access the backing field because it's private. Additionally, I think (and I may be wrong on this) that how the backing field is named/accessed is an implementation detail and could be different between platforms/versions. If you want to just find the fields because you know your types don't have fields declared, and thus you can find the auto-properties, then go to town with fields. – Chris Sinclair Dec 14 '12 at 21:09
  • 1
    @JavaSa I added another edit with using fields; they're quite similar. – Chris Sinclair Dec 14 '12 at 21:11
  • Thanks I did like this but instead of the **o** I have written: `Var fieldValue = field.GetValue(field.ReflectedType);` Which should be the same and I got some strange exception. Anyway, I wonder why do I need `GetFields` method if I can't access them this way. You are saying this is because they're private, okay , but I don't familiar with many public field members. So I'm a little bit confused about how to investigate fields which are generally private, what I understand is the iterating over properties instead of field. But again for what use is the `GetFields` :) – JavaSa Dec 14 '12 at 21:21
  • 1
    Fields and properties both have their uses so it makes sense to access both of them as desired by the developer. I'm not sure what your end-goal is of reflecting to obtain these values so I can't comment necessarily on which you should use. _Typically_, if you define an auto-property, then you would only access its content via the defined property. As for accessing it via `ReflectedType`, I've never used this member (I always supply the object instance) so I'm not sure why it's causing issues. I'd recommend you just pass through the object reference. – Chris Sinclair Dec 14 '12 at 21:31
  • Update: What you said is working for fields with o which is of Generic type as you mentioned in your second version. But I was refactoring my methods parameters to include it, I thought `field.ReflectedType == o` but it's not, any idea why? – JavaSa Dec 14 '12 at 21:32
  • 1
    @JavaSa Yeah, just realized: `ReflectedType` is actually pointing to the `Type` you obtained on the line `var type = o.GetType()` and _not_ `o` itself. It's a `Type` not an object instance. EDIT: In that sense, you cannot use it the way you were thinking (it's a different concept for a different usage) – Chris Sinclair Dec 14 '12 at 21:33
  • Thanks things were a little messed up :) – JavaSa Dec 14 '12 at 21:35