VS编译间接引用的DLL不一定输出
如果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 转载请注明出处。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- windows和linux下 Python2,Python3 的环境及安装
- entity-framework – 是否可以将Entity Framework与Windows
- 散列函数从整数坐标对提供唯一的uint
- windows-server-2008 – HTTP错误503.该服务不可用.在带有i
- laravel windows安装
- 在Windows上更改Git Bash(msy??sgit)中的OpenSSH和OpenSSL版
- 什么是win32报警,bzero,bcopy在移植c代码时的替代方法
- Windows主机和Linux Docker容器之间的通信
- windows-server-2008 – VMware ESX虚拟机,Windows 2008 Se
- Windows上的Java的“单一登录”(使用来自“凭据管理器”的凭