前言

今天偶然机会,翻了一下大学期间的书籍《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://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-define

https://blog.walterlv.com/post/how-to-define-preprocessor-symbols.html

.NET探索平台条件编译的更多相关文章

  1. ZTESoft 持续集成 编年史 之 持续集成探索---平台选择

    2012 年 7.8 月份,我们逐渐了解了持续集成的概念,同时我们家庭作坊的dailybuild方式不断爆出各种问题,并且已经无法满足日益增长的各种需求. 我们开始探索持续集成的不同实现方式,首先我们 ...

  2. 百度 LBS 开放平台,开发人员众測计划正式启动

    Hi各位亲爱滴开发人员:   你是否以前-- 期望第一时间率先接触到百度LBS开放平台的最新功能? 期望被邀请作为最最尊贵的首批试用志愿者感受志愿者的特权? 期望自己的意见被产品经理採纳.优化功能.从 ...

  3. 关于页ASP.NET面布局

    关于页面布局,充分利用Table和分层   从接触ASP.NET到现在已经有一段时间了,起初总是嫌麻烦,想找捷径,凡是想当然,结果导致自己反而走了不少的弯路. 起初刚开始接触ASP.NET的时候,发现 ...

  4. Web工程师必备的43款可视化工具

    国外站点DATAVISUALIZATION.CH为大家总结出了当前热用的43款可视化工具,包括Arbor.Chroma.js.D3.js.Google Chart Tools等,绝对让你一饱眼福. 1 ...

  5. 迎战大数据-Oracle篇

    来自:http://www.cnblogs.com/wenllsz/archive/2012/11/16/2774205.html 了解大数据带来的机遇: 透视架构与工具: 开源节流,获得竞争优势. ...

  6. 优化基于FPGA的深度卷积神经网络的加速器设计

    英文论文链接:http://cadlab.cs.ucla.edu/~cong/slides/fpga2015_chen.pdf 翻译:卜居 转载请注明出处:http://blog.csdn.net/k ...

  7. win8.1和wp8.1共用代码,需要注意的一些问题

    最近写了一个应有,使用了mvvmlight,把viewmodel.model.common之类的代码都放到了shared共享,写下来才发现,有不少问题是自已下手之前没注意到的,有些地方实在没法中途改了 ...

  8. R in action读书笔记(22)第十六章 高级图形进阶(下)

    16.2.4 图形参数 在lattice图形中,lattice函数默认的图形参数包含在一个很大的列表对象中,你可通过trellis.par.get()函数来获取,并用trellis.par.set() ...

  9. [AIR] as3 之条件编译多平台妙用

    http://bbs.9ria.com/thread-418864-1-1.html 一直希望as3 可以支持条件编译,即满足A时编译函数1,满足B时则编译函数2. 最佳百度了之后,发现原来是可以实现 ...

随机推荐

  1. gunicorn简单配置

    Gunicorn配置 # -*- coding: utf-8 -*- import os from multiprocessing import cpu_count bind = "127. ...

  2. base64 基本使用 和os模块使用

    1  base64 的基本使用 import base64 with open('../static/upload/63bc620d1594779d6a98c53a3a8db1e5.png','rb' ...

  3. [日常摸鱼]bzoj1007[HNOI2008]水平可见直线-半平面交(对偶转凸包)

    不会写半平面交-然后发现可以转成对偶凸包问题 具体见这里:http://trinkle.blog.uoj.ac/blog/235 相关的原理我好像还是不太懂-orz #include<cstdi ...

  4. MAC 安装Python3.7

    查看下python版本 macosdeMacBook:Versions macos$ cd /System/Library/Frameworks/Python.framework/Versions/ ...

  5. angular8 大地老师学习笔记---第八课

    /*ViewChild获取dom节点 1.模板中给dom起一个名字 <div #myBox> 我是一个dom节点 </div> 2.在业务逻辑里面引入ViewChild imp ...

  6. 行业动态 | 每日处理2500万事务数据的IoT解决方案

    借助DataStax Enterprise和其他开源的解决方案,Locstat为它的用户提供了创新的IoT解决方案,并将数据分析时间由2-3周降至数分钟内,从而快速生成用于分析的图数据.不仅如此,现在 ...

  7. Java 面试知识点【背诵版 240题 约7w字】

    -- 转载自牛客网 是瑶瑶公主吖 Java 基础 40 语言特性 12 Q1:Java 语言的优点? ① 平台无关性,摆脱硬件束缚,"一次编写,到处运行". ② 相对安全的内存管理 ...

  8. 中小学生的噩梦:怎样用Python检测抄袭行为?广大中小学生们的美梦就此结束

    本教程将介绍如何使用机器学习技术(如word2vec和余弦相似度等),在Python中用几行代码制作抄袭检测器.搭建完成后,抄袭检测器将会从文件中载入学生们的作业,然后通过计算相似度来判断学生有无相互 ...

  9. Python基础入门:注释、变量、运算符与数据类型

    一.为什么要学习python? python的特点 python作为一门脚本语言,在越来越多的行业和领域发挥着重大作用,比如机器学习.网站开发.数据分析.爬虫.自动化测试. 同时,python具备以下 ...

  10. C#动态实体集的反序列化(动态JSON反序列化)

    一.使用场景 我们在将 JSON 反序列化实体集的时候,如果字段是固定的,那么我们序列化非常简单,对应字段写的实体集就可以了.比如下面这种: { "data":[ { " ...