0 引言
最近准备把之前的公共类库移植为多目标框架,就研究了一下.Net Standard多目标框架类库的官方文档,且自己做了个格式,总算搞清楚了多目标框架类库引用继承和函数调用规则,为怕以往,在这里分享留档,以备不时之需。众所周知,.NET类库是向下兼容的,比如Net4.5可以引用Net4.0类库,Net4.6可以引用Net4.5类库,不同框架的函数可以通过#if进行框架版本限定,但是不同框架特定的函数是如何继承的,这里通过实验进行检验。
1 测试
1.1 修改项目文件为多目标框架类库
将
<PropertyGroup> <TargetFramework>netstandard1.0</TargetFramework> </PropertyGroup>
修改为
<PropertyGroup> <TargetFrameworks>net40;net45</TargetFrameworks> </PropertyGroup>
1.2 添加测试类
public class ProviderNetVersion { #if NET40 public static string GetNetVersion() { Console.WriteLine("NET40"); return "NET40"; } #endif #if NET45 public static string GetNetVersion() { Console.WriteLine("NET45"); return "NET45"; } #endif #if NET46 public static string GetNetVersion() { Console.WriteLine("NET46"); return "NET46"; } #endif }
1.3 创建Winform项目
分别创建Net4.0、Net4.5、Net4.6框架的三个WinForm程序调用公共类库的ProviderNetVersion.GetNetVersion() 方法,查看具体调用的是哪个目标框架的函数。
分别加入测试代码
Winform Net4.0
private void Form1_Load(object sender, EventArgs e) { Text = $@"Winform版本:Net4.0,引用类库版本:{ProviderNetVersion.GetNetVersion()}"; }
Winform Net4.5
private void Form1_Load(object sender, EventArgs e) { Text = $@"Winform版本:Net4.5,引用类库版本:{ProviderNetVersion.GetNetVersion()}"; }
Winform Net4.6
private void Form1_Load(object sender, EventArgs e) { Text = $@"Winform版本:Net4.6,引用类库版本:{ProviderNetVersion.GetNetVersion()}"; }
1.4 测试结果
2 结果分析
本例中只设置了<TargetFrameworks>net40;net45</TargetFrameworks> ,表示类库只会生成net40和net45的dll文件。
虽然定义了
#if NET46 public static string GetNetVersion() { Console.WriteLine("NET46"); return "NET46"; } #endif
但由于没有生成net46的dll文件,所以定义的NET46版本的GetNetVersion函数不会出现在生成的dll里。
Net4.6的Winform程序事实上是引用的NET45的类库,NET45的类库反编译后的函数定义如下:
using System; namespace Test{ // Token: 0x02000034 RID: 52 public class ProviderNetVersion { // Token: 0x06000205 RID: 517 RVA: 0x0000D194 File Offset: 0x0000B394 public static string GetNetVersion() { Console.WriteLine("NET45"); return "NET45"; } } }
所以就出现了前面的测试结果。
3 总结
测试结果显示,如果程序框架与类库框架一致,且包含特定版本的函数(通过#if指定),则使用同一版本的函数,如Winform Net4.0和Net4.5测试结果。
如果程序框架比类库框架版本新,则使用类库最新目标版本的函数,如Winform Net4.6测试结果。
这里留个问题:如果把#if NET45定义的函数注释掉,您认为测试结果会怎样?或者会出现什么错误?有疑问的可以留言,欢迎发邮箱18845116@QQ.COM进行交流。
public class ProviderNetVersion { #if NET40 public static string GetNetVersion() { Console.WriteLine("NET40"); return "NET40"; } #endif // #if NET45 // public static string GetNetVersion() // { // Console.WriteLine("NET45"); // return "NET45"; // } // #endif #if NET46 public static string GetNetVersion() { Console.WriteLine("NET46"); return "NET46"; } #endif }
附:
官方文档:https://docs.microsoft.com/en-us/dotnet/core/tutorials/libraries#how-to-multitarget
文章网址:https://www.cnblogs.com/easynetwork/p/13779531.html
作者:易几师
转载请保留