C# ‘dynamic’ cannot access properties from anonymous types declared in another assembly

后端 未结 8 2467
无人共我
无人共我 2020-11-27 16:22

Code below is working well as long as I have class ClassSameAssembly in same assembly as class Program. But when I move class ClassSameAssemb

相关标签:
8条回答
  • 2020-11-27 17:07

    I ran into a similair problem and would like to add to Jon Skeets answer that there is another option. The reason I found out was that I realized that many extension methods in Asp MVC3 uses anonymous classes as input to provide html attributes (new {alt="Image alt", style="padding-top: 5px"} =>

    Anyway - those functions use the constructor of the RouteValueDictionary class. I tried that myself, and sure enough it works - though only the first level (I used a multi-level structure). SO - in code this would be:

    object o = new {
        name = "theName",
        props = new {
            p1 = "prop1",
            p2 = "prop2"
        }
    }
    SeparateAssembly.TextFunc(o)
    
    //In SeparateAssembly:
    public void TextFunc(Object o) {
      var rvd = new RouteValueDictionary(o);
    
    //Does not work:
    Console.WriteLine(o.name);
    Console.WriteLine(o.props.p1);
    
    //DOES work!
    Console.WriteLine(rvd["name"]);
    
    //Does not work
    Console.WriteLine(rvd["props"].p1);
    Console.WriteLine(rvd["props"]["p1"]);
    

    SO... What is really going on here? A peek inside the RouteValueDictionary reveals this code (values ~= o above):

    foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values))
        object obj2 = descriptor.GetValue(values);
        //"this.Add" would of course need to be adapted
        this.Add(descriptor.Name, obj2);
    }
    

    SO - using TypeDescriptor.GetProperties(o) we would be able to get the properties and values despite the anonymous type being constructed as internal in a separate assembly! And of course this would be quite easy to extend to make it recursive. And to make an extension method if you wanted.

    Hope this helps!

    /Victor

    0 讨论(0)
  • 2020-11-27 17:10

    If you're already using Newtonsoft.Json in your project (or you're willing to add it for this purpose), you could implement that horrible extension method Jon Skeet is referring to in his answer like this:

    public static class ObjectExtensions
    {
        public static ExpandoObject ToExpando(this object obj)
            => JsonConvert.DeserializeObject<ExpandoObject>(JsonConvert.SerializeObject(obj));
    }
    
    0 讨论(0)
提交回复
热议问题