Wednesday, July 13, 2016

C# Reflection: Setting a private enum-type member variable with a private inner enum type value

Today, while creating a C# unit test, I had a situation where I needed to set the value of a private variable on the class under test.  The variable was an enum-type variable, where the enum type itself was a private inner type defined in the class under test.

(I won’t in this post get into why I ended up landing on doing this, instead of some other solution such as refactoring the actual class under test in order to avoid the need to do so, as that would be a separate discussion.)

This post describes the technique using reflection that I ended up using to accomplish this.

For example, given a class defined like:

class Card
{
    private Suit _suit;

    private enum Suit
    {
        Hearts,
        Diamonds,
        Clubs,
        Spades
    }
}

Given an instance of that class named card, I was able to set the value of that object's private _suit variable by doing:

using System.Reflection;

...

// Get a reference to the _suit member variable.
FieldInfo suitField = card.GetType().GetField("_suit", BindingFlags.NonPublic | BindingFlags.Instance);

// Get a reference to the Spades member of the Suit enum.
object spades = card.GetType().GetNestedType("Suit", BindingFlags.NonPublic).GetField("Spades").GetValue(card);

// Set the value of _suit on our card object to Spades.
suitField (card, spades);

This kind of reflection hackery probably isn’t a best practice in most situations! Still, I thought it might be helpful to record here as an aid for those rare situations where it does make sense to manipulate this kind of enum-type private variable for unit testing purposes.

1 comment:

  1. Thanks for posting this! It helped me out today :)

    ReplyDelete

Non-spammers: Thanks for visiting! Please go ahead and leave a comment; I read them all!

Attention SPAMMERS: I review all comments before they get posted, and I REPORT 100% of spam comments to Google as spam! Why not avoid getting your account banned as quickly -- and save us both a little time -- by skipping this comment form and moving on to the next one on your list? Thanks, and I hope you have a great day!