.NET探索平台条件编译
前言
今天偶然机会,翻了一下大学期间的书籍《C程序设计》,好吧,当我翻着翻着,翻到了符号常量(#define指令)中,是啊,这是一个预处理器指令,记得在Magicodes.IE中针对平台选择不同的库,哈哈,这是一个典型的根据平台进行条件处理,好吧,
根据这些内容,让我感觉在今天,我需要对#define指令以及在.NET中的平台条件处理,以及平台的条件编译进行记录一下。

define
我们可通过define来定义符号,然后将符号用在#if指令表达式中,如下所示:
#define PI
通过上面这些内容可能很难去了解这该如何使用,其实#define在我们的编码过程中也是很少去使用的,我们继续往下看。
其实对于预处理器,在我们调试以及运行时的作用是比较大的,比如说对某些代码限制编译,另一方变其实还可以对代码进行环境或者版本的控制,这些都是Ok的,最后我们结合着控制语句#if来看一下:
#define PI
using System;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
#if (PI)
Console.WriteLine("PI is defined");
#else
Console.WriteLine("PI is not defined");
#endif
Console.ReadKey();
}
}
}
当我们的头部声明#define PI时,我们也可以看到编译的感知功能可以为我们将控制语句进行切换,是啊,我们可以在头部进行声明。
条件编译符号
对于上面我们可以直接通过#define去进行条件编译,而对于在.cs文件中我们去定义它达到的只是局部的使用,我们如果说想全局的控制,全局的应用该如何操作?其实我们是可以通过DefineConstants属性进行操作。

我们可以打开项目文件进行查看,属性如下所示:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;PI</DefineConstants>
</PropertyGroup>
</Project>
当然了,我们一方面是可通过VS对项目的属性进行编辑,而另一方面,我们是可通过直接对项目文件进行修改编辑操作.这样其实达到了一个可控制性.
RuntimeInformation
对于代码中也是可以进行平台的逻辑判断的,在.NET Core 1.0的时候其实已经添加了System.Runtime.InteropServices.RuntimeInformation对于这个类的添加,使我们可以动态的去判断当前的操作系统(OS),以及我们可通过这些动态判断为我们的业务逻辑进行不同的处理行为。
判断当前操作系统如下所示:
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
Console.WriteLine("Running on Linux!");
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
Console.WriteLine("Running on macOS!");
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Console.WriteLine("Running on Windows!");
MSBuild & RuntimeInformation
对于条件编译,之前我们已经手动的操作过一次了,是我们可以根据不同的环境值进行对代码编译内容的控制,如果说我想根据当前的操作系统(OS)动态的进行条件编译,该如何进行操作。
其实我们在项目文件中进行调用System.Runtime.InteropServices.RuntimeInformation进行我们的条件处理。下面我们看一下在MSBuild中如何调用System.Runtime.InteropServices.RuntimeInformation如下所示:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5</TargetFramework>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
</PropertyGroup>
<Target Name="PrintRID" BeforeTargets="Build">
<Message Text="IsWindows $(IsWindows)" Importance="high" />
<Message Text="IsOSX $(IsOSX)" Importance="high" />
<Message Text="IsLinux $(IsLinux)" Importance="high" />
</Target>
</Project>
我们是可以通过visual studio或者说通过CLI直接运行构建命令dotnet build,我们在Windows操作系统中测试一下,输出结果如下所示:
C:\Users\hueif\source\repos\ConsoleApp2\ConsoleApp2>dotnet build
用于 .NET 的 Microsoft (R) 生成引擎版本 16.8.0+126527ff1
版权所有(C) Microsoft Corporation。保留所有权利。
正在确定要还原的项目…
所有项目均是最新的,无法还原。
你正在使用 .NET 的预览版。请查看 https://aka.ms/dotnet-core-preview
ConsoleApp2 -> C:\Users\hueif\source\repos\ConsoleApp2\ConsoleApp2\bin\Debug\net5\ConsoleApp2.dll
IsWindows true
IsOSX
IsLinux
可以看出,在IsWindows中对应着true,说明我们的操作生效了,那么我们继续修改我们的程序,看看如何使用条件编译,去控制我们的代码,我们在项目文件中添加如下片段:
<PropertyGroup Condition="'$(IsWindows)'=='true'">
<DefineConstants>Windows</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsOSX)'=='true'">
<DefineConstants>OSX</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinux)'=='true'">
<DefineConstants>Linux</DefineConstants>
</PropertyGroup>
通过如上语句,我们可以对DefineConstants属性进行条件判断,条件性处理,同样我们在代码中也是通过该值进行判断,如下所示:
static void Main(string[] args)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
Console.WriteLine("Running on Linux!");
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
Console.WriteLine("Running on macOS!");
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
Console.WriteLine("Running on Windows!");
#if Linux
Console.WriteLine("Build on Linux!");
#elif OSX
Console.WriteLine("Build on macOS!");
#elif Windows
Console.WriteLine("Build in Windows!");
#endif
Console.ReadKey();
}
下面我们来验证一下结果,是否跟我们想象中的一样
Running on Windows!
Build in Windows!
结果没问题,已达到预期的效果。
References
https://blog.walterlv.com/post/how-to-define-preprocessor-symbols.html
.NET探索平台条件编译的更多相关文章
- ZTESoft 持续集成 编年史 之 持续集成探索---平台选择
2012 年 7.8 月份,我们逐渐了解了持续集成的概念,同时我们家庭作坊的dailybuild方式不断爆出各种问题,并且已经无法满足日益增长的各种需求. 我们开始探索持续集成的不同实现方式,首先我们 ...
- 百度 LBS 开放平台,开发人员众測计划正式启动
Hi各位亲爱滴开发人员: 你是否以前-- 期望第一时间率先接触到百度LBS开放平台的最新功能? 期望被邀请作为最最尊贵的首批试用志愿者感受志愿者的特权? 期望自己的意见被产品经理採纳.优化功能.从 ...
- 关于页ASP.NET面布局
关于页面布局,充分利用Table和分层 从接触ASP.NET到现在已经有一段时间了,起初总是嫌麻烦,想找捷径,凡是想当然,结果导致自己反而走了不少的弯路. 起初刚开始接触ASP.NET的时候,发现 ...
- Web工程师必备的43款可视化工具
国外站点DATAVISUALIZATION.CH为大家总结出了当前热用的43款可视化工具,包括Arbor.Chroma.js.D3.js.Google Chart Tools等,绝对让你一饱眼福. 1 ...
- 迎战大数据-Oracle篇
来自:http://www.cnblogs.com/wenllsz/archive/2012/11/16/2774205.html 了解大数据带来的机遇: 透视架构与工具: 开源节流,获得竞争优势. ...
- 优化基于FPGA的深度卷积神经网络的加速器设计
英文论文链接:http://cadlab.cs.ucla.edu/~cong/slides/fpga2015_chen.pdf 翻译:卜居 转载请注明出处:http://blog.csdn.net/k ...
- win8.1和wp8.1共用代码,需要注意的一些问题
最近写了一个应有,使用了mvvmlight,把viewmodel.model.common之类的代码都放到了shared共享,写下来才发现,有不少问题是自已下手之前没注意到的,有些地方实在没法中途改了 ...
- R in action读书笔记(22)第十六章 高级图形进阶(下)
16.2.4 图形参数 在lattice图形中,lattice函数默认的图形参数包含在一个很大的列表对象中,你可通过trellis.par.get()函数来获取,并用trellis.par.set() ...
- [AIR] as3 之条件编译多平台妙用
http://bbs.9ria.com/thread-418864-1-1.html 一直希望as3 可以支持条件编译,即满足A时编译函数1,满足B时则编译函数2. 最佳百度了之后,发现原来是可以实现 ...
随机推荐
- apidoc学习(接口文档定义取代word)
apidoc的安装,参考:https://blog.csdn.net/qq_36386771/article/details/82149848 生产文档,需要先编写一个apidoc.json对接口文档 ...
- linux tar 压缩和解压缩
tar -c: 建立压缩档案-x:解压-t:查看内容-r:向压缩归档文件末尾追加文件-u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个. 下面 ...
- MySQL(一):MySQL数据库事务与锁
基本概念 事务是指满足ACID特性的的一组操作,可以通过Commit提交事务,也可以也可以通过Rollback进行回滚.会存在中间态和一致性状态(也是真正在数据库表中存在的状态) ACID Atomi ...
- MySQL 5.7.29安装配置
一.环境准备(关闭防火墙) 1.清除已安装数据库 [root@mysql01 ~]# rpm -qa | grep mariadb mariadb-libs-5.5.35-3.el7.x86_64 [ ...
- IOS UITableView 加载未知宽高图片的解决方案
在开发中遇到了UITableView列表 UITableViewCell装载图片但不知Image的宽高 问题. 在解决该问题的时候,首先想到的是异步加载图片 采用第三方框架SDWebImage 实现对 ...
- css进阶 01-CSS中的非布局样式
01-CSS中的非布局样式 #前言 CSS中,有很多非布局样式,这些样式(属性)和与布局无关,包括: 字体.字重.颜色.大小.行高 背景.边框 滚动.换行 装饰性属性(粗体.斜体.下划线)等. 这篇文 ...
- python 协程并发下载图片
1 import aiohttp 2 import asyncio 3 import time 4 5 async def dl_coroutine(session,url): 6 print('开始 ...
- 【收藏】关于元数据(Metadata)和元数据管理,这是我的见过最全的解读!
本文主要从元数据的定义.作用.元数据管理现状.管理标准和元数据管理功能等方面讲述了我对元数据(Metadata)和元数据管理的认知及理解. 元数据管理 一.元数据的定义 按照传统的定义,元数据(Met ...
- Python 写了一个批量生成文件夹和批量重命名的工具
Python 写了一个批量生成文件夹和批量重命名的工具 目录 Python 写了一个批量生成文件夹和批量重命名的工具 演示 功能 1. 可以读取excel内容,使用excel单元格内容进行新建文件夹, ...
- C# Socket使用以及DotNetty和Supersocket 框架
1.Socket服务端与客户端通话 1服务端 using System; using System.Collections.Generic; using System.Linq; using Syst ...