如果A引用B,B引用C,那么A对C就是间接引用,一般的编译A时会输出B的DLL,而因为B对C有引用,所以也会输出C的DLL。但是实际编译时发现,并不一定都会输出C的DLL。后面不断的追查原因,最终发现是与B对C引用时代码的调用有关。如果B对C的调用都是常量的方式,比如C中都是CONST常量,或者B只调用了C的CONST常量。那么编译的时候,B不会带上C的引用,这个可以ildasm工具,去查看B的DLL,然后可以看到引用的情况。

先来看C库的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace C
{public sealed class ClassC{public const string TC = "MY_CONST";}
}

再来看B库的代码

using C;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace B
{public class ClassB{public static string TestB(){return ClassC.TC + "=>call C ok";}}
}

再来看C的代码

using B;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;namespace A
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){var str = ClassB.TestB();MessageBox.Show(str);}}
}

A是winform程序,执行后的结果如下图

执行的结果是我们所期望的,那我们现在用ildasm来查看B编译生成的DLL

可以看到根本没有对C程序集的引用。那为什么代码却正确执行了呢?我们可以看B的TestB方法被编译后的情况,如下图

从图上可以看到代码中ClassC.TC已经被常量"MY_CONST"取代了,所以代码能够正常运行。

VS在编译的时候进行了智能的判断,在所有的常量都被替换成具体的值之后,没有再进行调用,比如方法、构造函数等,所以A引用B,B引用C,A对C虽然是间接引用,但是根本不需要该DLL,下面是A编译后的文件列表。

而B编译的结果却是C的DLL一定会输出的。

那么什么情况下又会将间接引用的C编译出来呢?只要B对C有方法或者可变量的调用就会编译输出C的DLL。比如C中将const常量改成static常量。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace C
{public sealed class ClassC{public static string TC = "MY_CONST";}
}

这时A中编译的结果如下

可以看到C的DLL被编译输出了。再用ildasm来看B中的引用情况。

可以看到有对C的引用。再看B中TestB方法的编译情况

B中调用ClassC的TC变量。这也从侧面说明const和static是不一样的,有的文章说const最终会被编译成static的常量,从这个角度来看,这个观点是有待商榷的。也有可能是旧版的VS是这样处理的,而新版的VS采用了新的编译策略。所用的VS截图如下

关于间接引用,大家还可以参考该文章。

https://www.cnblogs.com/gates/p/3224794.html

转载请注明出处。

VS编译间接引用的DLL不一定输出相关推荐

  1. 主讲:A1(老吴) 时间:2004-10-22 15:00 主题:0一点点编译。1解决DLL与EXE沟通时String和其它Memory的问题.2公布hmOlevariants.pas 3成批...

    主讲:A1(老吴) 时间:2004-10-22 15:00 主题: 0>一点点编译. 1>解决DLL与EXE沟通时String和其它Memory的问题. 2>公布hmOlevaria ...

  2. asp.net 调用(引用 Native dll 的)C++/CLI dll 的问题及解决

    asp.net 调用引用 native dll 的 C++/CLI dll 会报错:说是dll或其依赖项找不到.具体原因在于 IIS 只会从系统路径下去查找 native dll,不会查找 Bin 目 ...

  3. C# 中将所有引用的DLL 和exe文件打成一个exe文件(转)

    C#工程经常会引用多个DLL文件,形成一个完整的工程项目的目的.这样的工程在发布时,需要将编译形成的EXE文件与DLL文件共同发布.如果感觉麻烦,可以将这些DLL文件与EXE文件合并,最终形成一个更大 ...

  4. eclipse java转class_Eclipse中的Java项目:无法解析java.lang.Object类型。 它是从所需的.class文件间接引用的...

    Eclipse中的Java项目:无法解析java.lang.Object类型. 它是从所需的.class文件间接引用的 在Eclipse中导入项目后,我收到以下错误: 无法解析java.lang.Ob ...

  5. Mac 下编译 libmono.so 和 DLL 加密详解

    Unity 打出的安卓包为了防止反编译,需要对 Assembly-CSharp.dll 加密处理.Assembly-CSharp.dll 是由 libmono.so 运行时读取然后在 mono 虚拟机 ...

  6. C#中用ILMerge将所有引用的DLL和exe文件打成一个exe文件

    今天做了一个软件,想发布的时候才发现调用的类没几个,就像把它们都跟EXE文件打包在一起,以后复制去别的地方用也方便,于是上网搜了一下,发现网上大部分都是用ILMerge实现的,于是也自己试了一下,不过 ...

  7. php引用shell变量,Linux Shell Bash变量的间接引用 - Powered by PHPWind....

    假设一个变量的值是第二个变量的名字. 那么我们如何从第一个变量中取得第二个变量的值呢? 比如, 如果a=letter_of_alphabet并且letter_of_alphabet=z, 那么我们能够 ...

  8. JNI实现源码分析【三 间接引用表】

    在JNI实现源码分析[二 数据结构]的参数传递一节中,我们提到,JNI为了安全性的考虑使用了形如jobject的结构来传递参数.而jobject被表述为指针,但又不是直接指向Object的指针那么jo ...

  9. wxWidgets:使用 Open Watcom 编译的 WxWidgets 的 DLL 版本

    wxWidgets:使用 Open Watcom 编译的 WxWidgets 的 DLL 版本 wxWidgets:使用 Open Watcom 编译的 WxWidgets 的 DLL 版本 使用 O ...

  10. 在mingw编译环境下为dll添加版本信息

    在工程中,常常需要为dll添加版本信息,如果有vs工程比较好办,但是没有vs,在Mingw下也不难,通过对网上资料的搜集及验证,特分享. 1.假设有obj.c文件,内容如: #include<s ...

最新文章

  1. core data 学习笔记
  2. 多项式模2运算及求逆元
  3. Java学习日记----反射
  4. JavaScript操作大全整理(思维导图七--字符串函数)
  5. jstorm的acker实现
  6. 从Http的连接到WebSocket
  7. 任务58:19-尚硅谷-Java语言基础-String类型变量的使用
  8. CV领域的实验室及研究组
  9. firefox新标签页背景_如何更改或自定义Firefox的“新标签页”
  10. java 变量 英文_Java中的字符类型变量无论是中文,英文还是数字,都是占4字节。...
  11. 《国风·豳(bin)风·七月》
  12. java_home的配置
  13. c++ 求x的n次方
  14. 890-git安装教程github创建仓库
  15. Python之freshman04
  16. 【C深入】程序中的三国天下,栈,堆,静态内存
  17. JS高级程序设计读书笔记 (第九章 客户端检测)
  18. 快速应用计算机制作pop,9计算机练习题
  19. 安装包UI美化之路-在线安装包
  20. 初探Java设计模式2:结构型模式(代理模式,适配器模式等)

热门文章

  1. 位图的实战场景及源码分析
  2. 计算机控制摄像头拍照,ECap(win7及XP摄像头功能增强工具)
  3. mysqldump关于--set-gtid-purged=OFF的使用(好文章!!)
  4. MySQL gtid purge_MySQL中set gtid_purged的行为变更及对备份恢复的影响
  5. android 闹钟取消,android设置和取消闹钟
  6. 如何关闭wps热点,如何关闭wpscenter,如何关闭我的wps
  7. HTML 中划线 、 下划线 、上划线
  8. 被称为海淀妈妈四大神器之一的倾听者K3 硬件拆解
  9. AVX贴片钽电容标识
  10. C语言求1到1000素数之和,C语言实现1-1000中所有素数的和