C# 匿名对象作为参数不起作用

标签 c# .net dynamic anonymous-objects

https://dotnetfiddle.net/446j0U重现链接(在 .net 4.7.2 上失败,在 .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;
    }
} 

在同一函数中访问匿名对象工作正常,但当我尝试将其传递到函数中时,出现异常

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

<小时/>

由@RandRandom编辑:

由于赏金期即将结束,我决定编辑这个问题。

到目前为止给出的答案都未能真正回答手头的问题,而只是提供了避免错误的方法。

OP 明确表示(在评论中)他知道解决方法并且目前正在使用解决方法。

这些问题仍然存在

  1. 为什么在 OP 设置和 dotnetfiddle.net 上出现上述错误?
  2. 如果通过更新修复了错误,OP 需要更新哪些内容?
  3. 问题已在新编译器/.Net 版本/Visual Studio 版本中得到解决吗?

回顾一下到目前为止 OP 的信息:

  • VS 2017
  • .Net Framework 4.8

最佳答案

C# documentation说:

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.

有两种明显的方法:

1)用预定义替换匿名类型:

    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;
    }

这种方式限制你不能使用匿名类型。但它会工作得很好。

2) 或者如果您喜欢匿名类型,请使用 ExpandoObject 进行强制转换。

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

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

关于C# 匿名对象作为参数不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58937752/

相关文章:

c# - IsAssignableFrom 和 GetInterface 之间有什么区别?

c# - 十进制 ToString 格式,至少给出 1 位数字,没有上限

c# - 通过 EWS API 连接到 Office 365

C# 映射罗盘点和搜索

.net - 从 WSDL 文件逆向工程 Web 服务接口(interface)的最佳方法?

javascript - 为段落动态分配类

c# - 隐藏代码内的基本 html 标签

python - 如何在运行时动态更改实例的基类?

c# - 在 XPath Binding WPF 中转义单引号

c# - 如何在jquery中计算文件上传进度?