12

I'm trying to make a mod for a game in c# and I'm wondering if there's a way to change the value of a read only property using reflections.

sashoalm
  • 75,001
  • 122
  • 434
  • 781
canhedian
  • 149
  • 1
  • 1
  • 3
  • 3
    Duplicate: http://stackoverflow.com/questions/3706389/changing-read-only-properties-with-reflection – SquidScareMe Nov 12 '15 at 19:44
  • 3
    Readonly means just that, ReadOnly. It cannot be changed once it is assigned. What are you trying to accomplish? – JimmyV Nov 12 '15 at 19:44
  • 2
    This sounds like a [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Why do you even need to do that in the first place? – juharr Nov 12 '15 at 19:48

5 Answers5

11

In general, no.

Three examples:

public int Value { get { return _value + 3; } } // No

public int Value { get { return 3; } } // No

public int Value { get; private set; } // Yes

So, you can change the value of the property while this property has corresponding private, protected or internal field.

Mark Shevchenko
  • 7,937
  • 1
  • 25
  • 29
8

Try this:

typeof(foo).GetField("bar", BindingFlags.Instance|BindingFlags.NonPublic).SetValue(foo,yourValue)
ske57
  • 577
  • 4
  • 21
5

You can in both those scenarios:

readonly int value = 4;

and

int value {get; private set}

using

typeof(Foo)
   .GetField("value", BindingFlags.Instance)
   .SetValue(foo, 1000); // (the_object_you_want_to_modify, the_value_you_want_to_assign_to_it)

You cannot modify

int value { get { return 4; } }

though.

If it returns a calculated value like

int value { get { return _private_val + 10; } }

you would have to modify _private_val accordingly.

nozzleman
  • 9,529
  • 4
  • 37
  • 58
1

Yes, this is absolutely possible. Whether it is good practice or helpful to your purpose, I do not know. Going off of @ske57's great advice, here is a sample program that demonstrates reflection. The initial field value of 5 and the reflected field value of 75 are written to the console.

using System;
using System.Reflection;

namespace JazzyNamespace
{
    class Program
    {
        static void Main()
        {
            var reflectionExample = new ReflectionExample();
            // access the compiled value of our field
            var initialValue = reflectionExample.fieldToTest;

            // use reflection to access the readonly field
            var field = typeof(ReflectionExample).GetField("fieldToTest", BindingFlags.Public | BindingFlags.Instance);

            // set the field to a new value during
            field.SetValue(reflectionExample, 75);
            var reflectedValue = reflectionExample.fieldToTest;

            // demonstrate the change
            Console.WriteLine("The complied value is {0}", initialValue);
            Console.WriteLine("The value changed is {0}", reflectedValue);
            Console.ReadLine();
        }

    }

    class ReflectionExample
    {
        public readonly int fieldToTest;

        public ReflectionExample()
        {
            fieldToTest = 5;
        }
    }
}
Ben
  • 209
  • 2
  • 8
0

As Mark said there could be scenarios where you cannot as . Think that the property itself could be a function derived from other properties, members.

However you may want to try the mechanisms explained here:

Is it possible to set private property via reflection?

Community
  • 1
  • 1
Juan
  • 3,675
  • 20
  • 34