7

https://dotnetfiddle.net/446j0U link to reproduce (failed on .net 4.7.2 not on .net core)


public class TEST { 

   static public void Main(string[] args)
    {
        var test = new { Text = "test", Slab = "slab"};
        Console.WriteLine(test.Text); //outputs test
        Console.WriteLine(TEST.TestMethod(test));  //outputs slab
    }

    static public string TestMethod(dynamic obj)
    {
        return obj.Slab;
    }
} 

access to anonymous object in the same function is working OK but when I try to pass it in the function I'm getting exception

Run-time exception (line 14): Attempt by method 'DynamicClass.CallSite.Target(System.Runtime.CompilerServices.Closure, System.Runtime.CompilerServices.CallSite, System.Object)' to access type '<>f__AnonymousType0`2' failed.

Stack Trace:

[System.TypeAccessException: Attempt by method 'DynamicClass.CallSite.Target(System.Runtime.CompilerServices.Closure, System.Runtime.CompilerServices.CallSite, System.Object)' to access type '<>f__AnonymousType0`2' failed.] at CallSite.Target(Closure , CallSite , Object ) at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0) at TEST.TestMethod(Object obj) :line 14 at TEST.Main(String[] args) :line 9


Edit by @RandRandom:

Since the bounty period is almost over, I decided to edit this question.

The given answers so far all fail to actually answer the problem at hand and only give ways to avoid the error.

OP clearly stated (in comments) that he is aware of workarounds and is currently using a workaround.

Those questions still remain

  1. WHY is the mentioned error occuring on OPs setup and on dotnetfiddle.net?
  2. If the error got fixed with an update what would OP need to update?
  3. Got the problem fixed in a new compiler / .Net Version / Visual Studio version?

To recap here are OP's Information so far:

  • VS 2017
  • .Net Framework 4.8
Rand Random
  • 7,300
  • 10
  • 40
  • 88
user3038144
  • 95
  • 1
  • 6
  • 3
    Doing this is likely a very bad idea. That said, your code is working fine in both LinqPad 5 and 6, so I am unable to replicate. Anything special with your project setup? – Jonathon Chase Nov 19 '19 at 15:42
  • 3
    Can't reproduce the error. – Rand Random Nov 19 '19 at 15:42
  • 3
    Rand is rigth, no repro https://dotnetfiddle.net/usRSXU in .net core 3 but repro in 4.7.2 https://dotnetfiddle.net/PwtQxy . @RandRandom What framework did you try it on ? – xdtTransform Nov 19 '19 at 15:45
  • 1
    @xdtTransform - Windows 10 machine, .net 4.8 installed, target Framework of app no matter if .net 4.8, .net 4.7.2 still no repro – Rand Random Nov 19 '19 at 15:49
  • 1
    @RandRandom, good catch repro only on C# fiddle. @ user3038144, What framework are you working on? – xdtTransform Nov 19 '19 at 15:52
  • Also, [can't reproduce on rextester](https://rextester.com/JVB17776) – Zohar Peled Nov 19 '19 at 16:20
  • 1
    link to reproduce https://dotnetfiddle.net/446j0U – user3038144 Nov 19 '19 at 16:26
  • It seems only for .net 4.7.2 not for .net core – user3038144 Nov 19 '19 at 16:29
  • 2
    Just as a curious note, If you add newtonsoft to the nuget packages, but without altering the code, it works. https://dotnetfiddle.net/2Mm9Ln I think this problem is related to dotnetfiddle. – Luis Lavieri Nov 19 '19 at 16:34
  • What has an anonymous type to do with an dynamic object ? An anonymous type isn't dynamic. I found this here https://sebnilsson.com/blog/convert-c-anonymous-or-any-types-into-dynamic-expandoobject/ to create a wrapper for (any) object to a dynamic object. – Holger Nov 19 '19 at 16:38
  • as I understand it's creating expando dynamic object which is not must be . I have not see any limitation for dynamic. 'The dynamic type indicates that use of the variable and references to its members bypass compile-time type checking. Instead, these operations are resolved at run time. ' https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/reference-types – user3038144 Nov 19 '19 at 16:47
  • BTW I run it under debugger and you can see the object value there - just can't access it – user3038144 Nov 19 '19 at 16:50
  • I ran it in Visual Studio 2019 net472. And it worked just fine. Unable to reproduce. Could it just be a dotnetfiddle problem? – Thomas Heijtink Nov 19 '19 at 18:48
  • nope it comes from my VS 2017 and .net 4.8 – user3038144 Nov 19 '19 at 20:37
  • It seems a .DotNetFiddle bug, if you add a nugetpackage, it will work, nosense. – Stefano Balzarotti Nov 20 '19 at 08:44
  • 2
    It works for me even in VS2017 + 4.6.1. If it ever was a bug, it's fixed now, so why the bounty? – Simon Mourier Nov 23 '19 at 10:03
  • I still have it on VS 2017 and .net 4.8 and we can see it on demo so there is something - bug or setting or else – user3038144 Nov 23 '19 at 23:33
  • Did you test it in visual studio? – gandalf Nov 26 '19 at 13:08
  • yes please read comment above yours – user3038144 Nov 26 '19 at 15:18

5 Answers5

7

As C# documentation says:

Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first. The type name is generated by the compiler and is not available at the source code level. The type of each property is inferred by the compiler.

There are two obvious ways:

1) Replace anonymous type with pre-defined:

    public class Container {
        public string Test { get; set; }
        public string Slab { get; set; }
    }

    public static void Main(string[] args) {
        var test = new Container { Text = "test", Slab = "slab"};
        Console.WriteLine(test.Text); //outputs test
        Console.WriteLine(TestMethod(test));  //outputs slab
    }

    public static string TestMethod(dynamic obj) {
        return obj.Slab;
    }

This way restricts you not to use an anonymous type. But it will work fine.

2) or if you like anonymous types, use casting with ExpandoObject.

Documentation: https://learn.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?redirectedfrom=MSDN&view=netframework-4.8

Sample: https://sebnilsson.com/blog/convert-c-anonymous-or-any-types-into-dynamic-expandoobject/

Badri
  • 202
  • 4
  • 14
Egor Samets
  • 109
  • 2
  • 3
    Thank you Egor. I can't mark it as answer because it should work the way I'm using it (at least I need clear explanation from MS why it works in .net core). But it's the workaround I'm using. – user3038144 Nov 20 '19 at 14:16
2

This should work,

static public string TestMethod(dynamic obj) {
     return obj.GetType().GetProperty("Slab").GetValue(obj).ToString();
}
Berkay Yaylacı
  • 4,383
  • 2
  • 20
  • 37
0

You can use ExpandoObject for dynamic type of variables or dynamic parameters. https://learn.microsoft.com/en-us/dotnet/api/system.dynamic.expandoobject?redirectedfrom=MSDN&view=netframework-4.8

public class TEST { 

   static public void Main(string[] args)
    {
        dynamic test = new ExpandoObject();
        test.Text = "test";
        test.Slab = "slab";
        Console.WriteLine(test.Text);
        Console.WriteLine(TEST.TestMethod(test));
    }

    static public string TestMethod(dynamic obj)
    {
        return obj.Slab;
    }
} 
GDI89
  • 54
  • 3
0

This is a problem with .NET Fiddle. The code is working perfectly fine with the latest Visual Studio 2017 update (15.9.17) and .NET 4.7.2.

Kai Hartmann
  • 3,106
  • 1
  • 31
  • 45
-1

This is an issue with .Net framework. You have to use Datatype which already exist and use var. Alternate way to code this is to use dictionary.

demo

using System; 
using System.Collections.Generic;

public class TEST 
{ 
   static public void Main(string[] args)
    {
        var test =  new Dictionary<int, string>();
        test.Add(1,"One");
        Console.WriteLine(test); //outputs test
        Console.WriteLine(TEST.TestMethod(test));  //outputs slab
    }

    static public string TestMethod(dynamic obj)
    {
        foreach (KeyValuePair<int, string> item in obj)
        {
            Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
            return item.Value;
        }
        return "";   
    }
} 
pensum
  • 980
  • 1
  • 11
  • 25
Jin Thakur
  • 2,711
  • 18
  • 15