Viku
Viku

Reputation: 2973

Instance variable modification during runtime using reflection

I have been through the below code . Here i am not able to get/set the value of the variable during runtime . Variable value has been taken through console .

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace ReflectionTest
{
    class Addition
    {
        public  int a = 5, b = 10, c = 20;
        public Addition(int a)
        {
            Console.WriteLine("Constructor called, a={0}", a);
        }
        public Addition()
        {
            Console.WriteLine("Hello");
        }
        protected Addition(string str)
        {
            Console.WriteLine("Hello");
        }

    }

    class Test
    {
        static void Main()
        {
            //changing  variable value during run time
            Addition add = new Addition();
            Console.WriteLine("a + b + c = " + (add.a + add.b + add.c));
            Console.WriteLine("Please enter the name of the variable that you wish to change:");
            string varName = Console.ReadLine();
            Type t = typeof(Addition);
            FieldInfo fieldInfo = t.GetField(varName ,BindingFlags.Public);
            if (fieldInfo != null)
            {
                Console.WriteLine("The current value of " + fieldInfo.Name + " is " + fieldInfo.GetValue(add) + ". You may enter a new value now:");
                string newValue = Console.ReadLine();
                int newInt;
                if (int.TryParse(newValue, out newInt))
                {
                    fieldInfo.SetValue(add, newInt);
                    Console.WriteLine("a + b + c = " + (add.a + add.b + add.c));
                }
                Console.ReadKey();
            }
       }
    }
  }

Thanks in advance ..

Upvotes: 0

Views: 253

Answers (2)

Simon Whitehead
Simon Whitehead

Reputation: 65059

There are multiple issues.

Firstly, you're passing BindingFlags.NonPublic. This won't work. You need to pass BindingFlags.Public and BindingsFlags.Instance like this:

t.GetField(varName, BindingFlags.Public | BindingFlags.Instance);

Or, just don't do it at all:

t.GetField(varName);

You can pass nothing at all because the implementation of GetField is this:

return this.GetField(name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);

So it does it for you.

Also, you need to pass instances of Addition to GetValue and SetValue, like so:

Console.WriteLine("The current value of " + 
    fieldInfo.Name + 
    " is " + 
    fieldInfo.GetValue(add) + ". You may enter a new value now:");
//                     ^^^ This

..and..

fieldInfo.SetValue(add, newInt);
//                 ^^^ This

Upvotes: 1

Danny Varod
Danny Varod

Reputation: 18069

The fields in your class are instance specific and public, yet you are using the noon public binding flag instead of the public binding flag and not applying the instance binding flag (using | for bitwise or).

Upvotes: 1

Related Questions