如果Dll中有某个类的方法返回dynamic实例,并且dynamic对象实际实例为匿名类类型,则Dll的外部使用者可能最终无法正常使用此dynamic对象。当使用此dynamic对象时,可能会遇到x属性没有在object中定义的错误,此错误属于Microsoft.CSharp.RuntimeBinder.RuntimeBinderException实例——即使Debug时,能够看到返回的对象实例确实含有x属性。

这很诡异,返回匿名类,并用dynamic进行标示是节省代码量的利器。但在此处,运行时却无法发现动态的对象类型。经过多次试验,再说明一下会出现此问题的场景:

环境为.Net Framework 4.6 & Visual Stdio 2015 Community.

在Dll中定义类方法,并返回dynamic。实际返回类型为匿名类型。

/// <summary>
/// 类库工程
/// </summary>
namespace dynamicdll
{public class Student{public static dynamic GenerateOne(){return new { No = "1", Name = "Dong", Age = 29 };}

在Dll外部调用此方法,打印其属性值。DLL外部是指在DLL工程外部,而不是不同的命名空间。

namespace LimsTest
{class Program{static void Main(string[] args){var st = GenerateOne();Debug.WriteLine($"{st.No},{st.Name},{st.Age}");

运行以上测试代码,出现错误。

测试方法:

  1. 在同一个.csproject中,相同的代码、使用方法不会出现此问题。
  2. 在dll项目内部使用,不会出现问题。
  3. 只有在dll中定义,外部使用才会出现问题。

可能的原因:

  1. 程序加载Dll的一些特殊之处。可能是AppDomain加载DLL的一些机制问题。
  2. 如果字段、方法参数或者返回值的类型是dynamic,编译器会将该类型转换为System.Object,并在元数据中向字段、参数或返类型应用System.Runtime.CompilerService.DynamicAttribute的实例。从上图的错误中可以看到返回的对象已经被转换为Object,但却没有能成功应用Runtime binding。外部调用后,Runtime没有找不到合适的、或者不知道如何在执行动态运行转换。如果跟踪调试,虽然可以看到类型为匿名类,并且拥有属性(值),但是运行会失败。

解决方案:

返回非dynamic对象。

不要使用匿名对象作为dynamic的返回值。使用确定的、在DLL中明确定义的类,返回dynamic不会出现错误。

总结:

不要在DLL中向其外部使用者返回实际类型为匿名类的dynamic对象实例。

转载于:https://www.cnblogs.com/jjseen/p/5530997.html

Dll中的方法向外返回dynamic类型可能会失败相关推荐

  1. 重学Java(035)——Java基础知识(类作为成员变量、接口作为成员变量、接口作为方法参数和返回值类型)

    学习内容:三种引用类型用法 一.类作为成员变量 二.接口作为成员变量 三.接口作为方法参数和返回值类型 实际的开发中,引用类型的使用非常重要,也是非常普遍的.我们可以在理解基本类型的使用方式基础上,进 ...

  2. StrUtil.removeAll,java: 无法将类 cn.hutool.core.text.CharSequenceUtil中的方法 removeAll应用到给定类型;

    情况及问题 //原始代码 String s = StrUtil.removeAll(data, "{", "\"", "[", & ...

  3. 使用反射获得jar包中的类、方法、参数、返回值类型,然后动态加载jar包运行方法

    其实我的需求是在系统中 测试用户导入的jar包,所有网上找了很多解决方案,踩过很多坑,再加上以前搞c++的,对java不是很熟, 这里特意记录下,算是基本满足需求了 使用反射获得jar包中的类.方法. ...

  4. 64位进程调用32位dll的解决方法 / 程序64位化带来的问题和思考

    最近做在Windows XP X64,VS2005环境下做32位程序编译为64位程序的工作,遇到了一些64位编程中可能遇到的问题:如内联汇编(解决方法改为C/C++代码),long类型的变化,最关键的 ...

  5. 64位进程调用32位dll的解决方法

    最近做在Windows XP X64,VS2005环境下做32位程序编译为64位程序的工作,遇到了一些64位编程中可能遇到的问题:如内联汇编(解决方法改为C/C++代码),long类型的变化,最关键的 ...

  6. JAVA不同类型数组重载_java学习笔记--java中的方法与数组

    方法 完成特定功能的代码块 方法的格式 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2...){ //方法体 return 返回值: } 方法的调用方式 通过方法名调用方法 根据形 ...

  7. 定义银行账户类Account,有属性:卡号cid,余额balance,所属用户Customer 银行账户类Account有方法: (1)getInfo(),返回String类型,返回卡的详细信息

    //定义银行账户类Account,有属性:卡号cid,余额balance,所属用户Customer //银行账户类Account有方法: //(1)getInfo(),返回String类型,返回卡的详 ...

  8. java中read方法

    InputStream in = null;in = new BufferedInputStream(new FileInputStream("src/nomal_io.txt") ...

  9. OC中的方法、设置器与访问器、便利初始化函数及便利构造器的相关问题

    OC中的方法 方法:类的功能代码,在<.h>文件中声明,在<.m>文件中实现. 语法: -|+(返回值类型)方法名:(参数类型)参数名 { //方法体 } 示例: -(void ...

  10. Java中的方法覆盖

    一.Java中的方法覆盖 1.方法覆盖又称为方法重写,英语单词:override/overwrite 2.使用: 当父类中的方法已经无法满足当前子类的业务需求,子类有必要将父类中继承过来的方法进行重新 ...

最新文章

  1. java 基础知识八 正则表达式
  2. 要做服务和酒店行业的“领英” ,Industry 获得230万美元种子轮融资
  3. 《软件工程》总结——第十一章
  4. 802.11协议中的action帧的使用
  5. 使用VMware VSphere WebService SDK进行开发 (三)——获取主机(HostSystem)的基本信息
  6. jQuery必知必熟基础知识
  7. 面试突击32:为什么创建线程池一定要用ThreadPoolExecutor?
  8. 计算机应用基础问题,计算机应用基础常见问题
  9. DevOps使用教程 华为云(17)git 比较2个分支版本的差异 某个具体文件的差异
  10. Windows Phone 7(WP7)开发 获取网络状态
  11. stolz定理考研能用吗_这些高数定理,2021二战考研租房的你千万别记混
  12. 软件项目开发成本估算方法
  13. 电脑玩CF、DNF、LOL等游戏掉帧.卡顿.黑屏怎么办?驱动人生十大游戏检测图文教程
  14. TalkingData Ad Tracking开启反作弊模式
  15. 三方支付之支付宝支付实现逻辑
  16. 使用 SQL 加密函数实现数据列的加解密
  17. Spring全家桶(四)Bean的生命周期
  18. 浅谈tomcat优化
  19. SOA构建电子政务平台 可用多种通信手段访问
  20. 全球与中国塑料面漆喷涂器市场深度研究分析报告

热门文章

  1. 【数据库原理实验(openGauss)】事务与并发控制
  2. Hive date_format函数入门
  3. PE学习.动手写PE.见缝插针
  4. JavaScript学习——JavaScript 循环
  5. 详解JS中的事件机制(带实例)
  6. python接口自动化测试(五)-其它(认证代理超时配置)
  7. mysql优化概述2
  8. 【高德LBS开源组件大赛】iOS版地图选中Overlay功能组件
  9. C3P0的几种使用方法(非JNDI)
  10. CCSpriteBatchNode(附:CCMenu与CCSpriteBatchNode的问题)