views:

199

answers:

3
+3  Q: 

C# 4.0 dynamics

Hi. Code bellow is working well until I have class ClassSameAssembly in same assembly as class Program. But when I move class ClassSameAssembly to separate assembly I have runtime error. Is it posible to resolve it?

using System;

namespace ConsoleApplication2
{
public static class ClassSameAssembly
   {
  public static dynamic GetValues()
     {
     return new
               {
                  Name = "Michael", Age = 20
               };
     }
  }

internal class Program
  {
  private static void Main(string[] args)
     {
     var d = ClassSameAssembly.GetValues();
     Console.WriteLine("{0} is {1} years old", d.Name, d.Age);
     }
  }
}
A: 

Instead of returning dynamic from the GetValues function, try returning object and declare the variable as dynamic:

public static object GetValues()
{
    return new
    {
        Name = "Michael", 
        Age = 20
    };
}

And call the function like this:

dynamic d = ClassSameAssembly.GetValues();
Console.WriteLine("{0} is {1} years old", d.Name, d.Age);
Darin Dimitrov
Doesn't work. Same result.
mehanik
I doubt that that will help - notice that this is an *execution-time* exception, not a compile-time error. The compiler knows that the method was declared as "dynamic" because it will have the appropriate attribute. If it didn't, the code wouldn't compile to start with.
Jon Skeet
+3  A: 

I believe the problem is that the anonymous type is generated as internal, so the binder doesn't really "know" about it as such.

Try using ExpandoObject instead:

 public static dynamic GetValues()
 {
     dynamic expando = new ExpandoObject();
     expando.Name = "Michael";
     expando.Age = 20;
     return expando;
 }

I know that's somewhat ugly, but it's the best I can think of at the moment... I don't think you can even use an object initializer with it, because while it's strongly typed as ExpandoObject the compiler won't know what to do with "Name" and "Age". You may be able to do this:

     dynamic expando = new ExpandoObject()
     {
         { "Name", "Michael" },
         { "Age", 20 }
     };
     return expando;

but that's not much better...

You could potentially write an extension method to convert an anonymous type to an expando with the same contents via reflection. Then you could write:

 return new { Name = "Michael", Age = 20 }.ToExpando();

That's pretty horrible though :(

Jon Skeet
Thanks. Now all ok.
mehanik
A: 

You could use [assembly: InternalsVisibleTo("YourAssemblyName")] to make you assebly internals visibile.

ema