0

C# Question .Net version 4.6.1

I have a class as shown below and in a function I create an instance of the class. I would like to create a reference to field(s) from the class instance and call the method "Insert" on the class variables "Name" and "Description".

I used a google search for: "Get reference to class field via reflection in C#". I did find information on stackoverflow for reflection but it does not talk about calling methods. I was able to use some of it to find what looks like a pointer. However I could not make it all the way to calling methods on the reference. I either am asking Google the wrong question or what I am trying to do is not possible.
C# Reflection - Get field values from a simple class

    Class AClass1
    {
        public String Action = String.Empty;
        public List<KeyValuePair<String, String>> Description = new  List<KeyValuePair<string, string>>();
        public List<KeyValuePair<String, String>> Name= new List<KeyValuePair<string, string>>();
    }


    // Psudo code:
    // The code has been reduced down to show the problem.  Error handling
    // etc has been removed. This may not compile because I had to 
    // reduce down the code to show what I am trying to accomplish. Any
    // suggestions for creating a reference to a class variable and calling
    // its methods would be appreciated.  If needed I can create a small 
    // sample that does compile but I think the sample provided shows 
    // what I am trying to accomplish.  If not let me know and I will
    // scale down further.


public void ProcessFeature1(String fieldName, String value1, String value2)
{
    AClass1 featureToManage = new AClass1();

    KeyValuePair<string, string> entry = new KeyValuePair<string, string>(value1, value2);
    if (entry != null)
    {
        // something along these lines is preferred if possible
        var ptrField = featureToManage.GetType().GetField(fieldName).FieldHandle;
        if (ptrField != null)
        {
            // the problem is figuring how to turn the value from reflection into
            // something I can call directly.  I have tried casting to the same
            // type as the variable in the class (not shown here) 
            // but it did not work or I did it wrong.  When I say it does not
            // work the run-time information does not show the method and the
            // compiler complains generally saying no such method Insert found.
            ptrField.Insert(0, entry);
        }
        else
        {
            // this works but would prefer to lookup the
            // the field in the class and call methods so I
            // 1. have less code
            // 2. do not have to hard code the name of the field.
            switch (fieldName)
            {
                case "Name":
                    {
                        featureToManage.Name.Insert(0, entry);
                        break;
                    }
                case "Description":
                    {
                        featureToManage.Description.Insert(0, entry);
                        break;
                    }
                default:
                    {
                        // something bad happened
                        break;
                    }
            }
        }
    }
}
user8916597
  • 23
  • 1
  • 4

1 Answers1

2

It sounds like you are looking for the GetValue() method.

Once you have gotten the FieldInfo from the Type using GetField(), you just need to call its GetValue() method, passing the object instance that you want to get the field value from (in this case featureToManage), and then cast the resulting value to the appropriate type (in this case List<KeyValuePair<string, string>>).

Here is what it looks like in code:

public void ProcessFeature1(string fieldName, string value1, string value2)
{
    AClass1 featureToManage = new AClass1();

    // Get the FieldInfo for the requested fieldName
    FieldInfo fieldInfo = featureToManage.GetType().GetField(fieldName);

    // Use the fieldInfo to get the value of the field from the target instance
    var targetList = (List<KeyValuePair<string, string>>)fieldInfo.GetValue(featureToManage);

    // now we can use the value as normal
    var entry = new KeyValuePair<string, string>(value1, value2);
    targetList.Insert(0, entry);
}

Note that in C# 6 you can use the nameof() operator to avoid hardcoding class, field and property names when using reflection, e.g.:

ProcessFeature1(nameof(AClass1.Description), "foo", "bar");
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300