2

I have a static method in MyLibrary1 which returns a dynamic object.

public static dynamic GetObjects()
{
return new { test = "something" };
}

But when I access the above method from MyLibrary2, debugger shows the value and object returned correctly.

dynamic b = MyLibrary1.GetObjects();
string name = b.test;

I get a RuntimeBinderException that says " 'object' does not contain a definition for 'test' when I read b.test.

The same code works as expected when I move the method to the calling library.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
Libin TK
  • 1,477
  • 2
  • 25
  • 46
  • 1
    Wow, this is very peculiar indeed. I've edited the title/question a little bit to make it more clear that this is a runtime exception. – Jonathon Reinhart Aug 04 '13 at 03:26
  • 1
    I confirmed this with a console app and class library, both targeting .NET 4, and both referencing `Microsoft.CSharp.dll`. Like the OP indicated, this works fine for me when calling the method from the console app directly. But putting the exact same code in a library causes the exception. *Paging @EricLippert !* – Jonathon Reinhart Aug 04 '13 at 03:27

2 Answers2

5

Anonymous types are not public, and dynamic does not mean you can break into something internal/private and use it. Reflection does though.

You can allow other assembly to use internal types using attribute:

// specified in assembly, defining MyLibrary1 class
[assembly: InternalsVisibleTo("Assembly, where you call MyLibrary1.GetObjects()")]

which completely fixes the issue with using anonymous type through dynamic.

Note that it means all internal types are accessible by specified assembly.

max
  • 33,369
  • 7
  • 73
  • 84
  • Checkout this answer - it suggests more standard way to move domain entities across assemblies: http://stackoverflow.com/a/2630439/739558 – Roi Shabtai Oct 08 '15 at 08:31
0

I'm not sure where to include this additional information.

I confirmed this with a console app and class library, both targeting .NET 4, and both referencing Microsoft.CSharp.dll. I'm comparing the results returned by the function in the same console app, to the one returned from the library.

When calling d.GetType().GetProperties(), both of them show the single property test that you've defined.

Not surprisingly then, this works for both of them:

    static string GetStringPropertyValue(dynamic d, string propertyName)
    {
        Type t = d.GetType();

        return t.GetProperty(propertyName).GetValue(d, null);
    }

So I'm very befuddled as to why that works, but simply getting the .test property does not work for both of them.

Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328