5

I recently had an interview with C# questions. One of them I cannot find an answer to.

I was given a class, looks like this:

public class Stick
{
    private int m_iLength;
    public int Length
    {
        get
        {
            return m_iLength;
        }
        set
        {
            if (value > 0)
            {
                m_iLength = value;
            }
        }
    }
}

Also, a main class was given

static void Main(string[] args)
{
    Stick stick = new Stick();
}

The task was to add code to the main that will cause m_iLength in the Stick class to be negative (and it was stressed out that it can be done).

I seem to miss something. The data member is private, and as far as I know the get and set function are by value for type int, so I do not see how this can be done.

Manfred Radlwimmer
  • 13,257
  • 13
  • 53
  • 62
IdoZ
  • 63
  • 3
  • 3
    reflection maybe? – slawekwin Aug 25 '16 at 06:22
  • 5
    Example: http://stackoverflow.com/questions/10862747/access-private-fields – bobah75 Aug 25 '16 at 06:23
  • 1
    @Sayse in C# you can't override class members unless they are declared "virtual" (contrast with Java for example). Reflection is the only way I can see (short of modifying the underlying IL, or using unsafe code to modify the memory backing iLength - not even sure if that last one is possible!) – RB. Aug 25 '16 at 06:31
  • Is it possible to override a non-virtual property or access the private members of the super class? – Harald Coppoolse Aug 25 '16 at 06:32
  • Even if you could override the property, you could not set the field value in it because it's private. – slawekwin Aug 25 '16 at 06:34

1 Answers1

4

Reflection is always the most direct:

var type = typeof(Stick);
var field = type.GetField("m_iLength", BindingFlags.NonPublic |BindingFlags.GetField | BindingFlags.Instance);
field.SetValue(stick, -1);
Console.WriteLine(stick.Length);

Explanation:

The first line gets the Type object for Stick, so we can get the private fields later on.

The second line gets the field that we want to set by its name. Note that the binding flags are required or field will be null.

And the third line gives the field a negative value.

Sweeper
  • 213,210
  • 22
  • 193
  • 313