RuntimeBinderException – “does not contain a definition for”

I thought I’d share an issue that I encountered recently with dynamic binding in C#, quite simply because I couldn’t easily find a solution out there on the net. In the end, it took the technical genius of a colleague of mine to identify the issue, and provide the solution.

The problem manifested itself when a test project was attempting to test a property on the Class Under Test of type object. At runtime this type was populated with an anonymous type by the Class Under Test.

At this point, it is probably more instructive to conjure a contrived example.

Consider a simple class library:

public class ClassUnderTest
{
    public object GetAnon()
    {
        return new { hint = 1 };
    }
}

Note that we return an anonymous type from the method, implicitly upcasting it to object. The anonymous type is declared within the method within the class, and so is treated by the compiler as internal to the class.

Now let’s consider a simple console application that attempts to access it.

private static void Main(string[] args)
{
    ClassUnderTest c = new ClassUnderTest();
    dynamic d = c.GetAnon();
    Console.WriteLine(d.member.hint);
}

The method GetAnon() of ClassUnderTest returns an object, thus denying us access to the members of the anonymous type. At this point we can access the properties via reflection, or if we’re being lazy (and naughty) set up an identical anonymous type and compare hash codes. (This is not to be encouraged: Principally because different types may generate the same hash, but there are other reasons which are outlined here on StackOverflow: http://stackoverflow.com/questions/16517392/is-it-safe-to-use-gethashcode-to-compare-identical-anonymous-types)

As it is, the solution above uses dynamic typing to achieve this effect. However, when you run it, the program throws a RuntimeBinder Exception:

‘object’ does not contain a definition for ‘member’

This is not a very helpful error message, and gives little clue as to the potential solution.

The problem is that because the anonymous type is internal to the declaring assembly, our client assembly cannot actually access this. To solve this, we have to make the assembly internal visible to the client application, which in this case is the unit test project.

We can emulate this in our sample solution by modifying AssemblyInfo.cs within ClassUnderTest  to contain the following:

[assembly: InternalsVisibleTo("ConsoleApplication1")]

In our real-world project we have to make internal of the Class Under Test visible to the test project.

One thought on “RuntimeBinderException – “does not contain a definition for”

Leave a Reply