9

I am trying to create a function that can return a field from its object.

Here is what I have so far.

public class Base
{
    public string thing = "Thing";
    public T GetAttribute<T>(string _name)
    {
        return (T)typeof(T).GetProperty(_name).GetValue(this, null);
    }
}

What I would ideally like is to call:

string thingy = GetAttribute<string>("thing");

but I have a feeling I got the wrong end of the stick when reading up on this because I keep getting null reference exceptions.

Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74
inadequateMonkey
  • 115
  • 1
  • 1
  • 9
  • Use the following answer from [here](http://stackoverflow.com/questions/1196991/get-property-value-from-string-using-reflection-in-c-sharp) – George Papadakis Dec 30 '15 at 14:43
  • 2
    Note that in C#, the term 'attribute' has a specific meaning: it's a piece of meta-data that can be attached to classes or methods, among other things. That's not what your question is about - the correct terms would be that you're using 'reflection' to get the value of a 'field' or 'property'. – Pieter Witvoet Dec 30 '15 at 14:48

2 Answers2

9

First thing - thing is a field, not a property.

Another thing is that you have to change parameter type to get it working:

public class Base {

   public string thing = "Thing";

   public T GetAttribute<T> ( string _name ) {
      return (T)typeof(Base).GetField( _name ).GetValue (this, null);
   }   
}

BTW - you can get property/field value by referencing an instance:

var instance = new Base();
var value = instance.thing;
kamil-mrzyglod
  • 4,948
  • 1
  • 20
  • 29
  • thank you very much, that works a charm! i have only one issue, which is my fault for not mentioning before, Base is going to be inherited by other things, is there a way to say a kind of " typeof ( this ) " type thing? – inadequateMonkey Dec 30 '15 at 14:46
  • thanks for the BTW too, i know this seems highly illogical but there is a very long and complicated reason for needing this, i wont go into it :) – inadequateMonkey Dec 30 '15 at 14:49
  • 1
    @inadequateMonkey use `this.GetType()` instead of `typeof(Base)` – Ivan Stoev Dec 30 '15 at 14:55
8

thing is a field not a property. You should use GetField method instead of GetProperty. Another problem is you are looking in typeof(T). You should look for the field in typeof(Base).

The whole function should be changed to

public T GetAttribute<T>(string _name)
{
    return (T)GetType().GetField(_name).GetValue(this);
}

If you want to have an extension method to get field value of a type you can use this

public static class Ex
{
    public static TFieldType GetFieldValue<TFieldType, TObjectType>(this TObjectType obj, string fieldName)
    {
        var fieldInfo = obj.GetType().GetField(fieldName,
            BindingFlags.Instance | BindingFlags.Static |
            BindingFlags.Public | BindingFlags.NonPublic);
        return (TFieldType)fieldInfo.GetValue(obj);
    }
}

Use it like

var b = new Base();
Console.WriteLine(b.GetFieldValue<string, Base>("thing"));

Using BindingFlags will help you to get field value even if it is private or static field.

Hamid Pourjam
  • 20,441
  • 9
  • 58
  • 74
  • Can you explain the reason for downvote so I can improve my answer? – Hamid Pourjam Dec 30 '15 at 14:37
  • This solves only a part of a problem - there are clearly problems with parameter type. – kamil-mrzyglod Dec 30 '15 at 14:37
  • thanks, i changed it to : return (T) typeof( T ).GetField ( _name ).GetValue ( this ); but still no joy – inadequateMonkey Dec 30 '15 at 14:37
  • `return (T)typeof(Base).GetField(_name).GetValue(this);` should probably be `return (T)GetType().GetField(_name).GetValue(this);` - since you're explicitly passing `this` in. Otherwise, it will break when trying to access fields/properties of the sub class (if any). – Rob Dec 30 '15 at 14:59