首页 / 知识
C#预处理器
2023-04-13 19:00:00

C# Preprocessor尽管C#规范确实包含预处理程序和基本指令(#define,#if等),但该语言没有像C / C ++这样的语言中具有相同的灵活预处理程序。我相信缺少如此灵活的预处理器是Anders Hejlsberg的设计决定(尽管很遗憾,我现在找不到对此的参考)。从经验来看,这当然是一个不错的决定,因为当我做很多C / C ++时,已经创建了一些非常糟糕的,不可维护的宏。 也就是说,在许多情况下,我可以找到稍微灵活一些的预处理器有用。可以通过一些简单的预处理程序指令来改进如下代码:
编写一个预处理器来处理这种极其简单的情况是一个好主意吗?史蒂夫·麦康奈尔(Steve McConnell)在《代码完成》(Code Complete,p208)中写道:
我被撕裂了。将这样的灵活预处理器排除在C#之外是一项设计决定。但是,我高度尊重的一位作者提到在某些情况下可能还可以。 我应该建立一个C#预处理器吗?有没有一种可以做我想做的简单事情? 考虑看一下诸如PostSharp之类的面向方面的解决方案,该解决方案基于事实基于自定义属性注入代码。它与预编译器相反,但是可以为您提供所需的功能(PropertyChanged通知等)。
您始终可以使用C预处理器-C#就语法而言足够接近。 M4也是一个选择。 我知道很多人认为短代码等于优雅代码,但事实并非如此。 如您所展示的,您提出的示例已通过代码完美地解决了,您需要预处理器指令做什么?您不想"预处理"您的代码,而是希望编译器在属性中为您插入一些代码。这是通用代码,但这不是预处理器的目的。 以您的示例为例,您将限制放在哪里?显然,这满足了观察者模式,并且毫无疑问将是有用的,但是实际上有很多事情会有用,因为代码提供了灵活性,而预处理器则没有。如果您尝试通过预处理器指令来实现通用模式,您将以需要与语言本身一样强大的预处理器结尾。如果您想以不同的方式处理代码,请使用预处理器指令,但是如果您只想要代码片段,则可以找到另一种方式,因为预处理器不是要这样做。 使用C ++风格的预处理器,OP的代码可以简化为这一行:
OBSERVABLE_PROPERTY或多或少看起来像这样:
如果您要处理100个属性,则大约需要1200行代码,而不是大约100行。哪个更容易阅读和理解?哪个更容易写? 使用C#,假设您剪切并粘贴以创建每个属性,则每个属性8个粘贴,总共800个。使用宏,根本没有粘贴。哪一个更有可能包含编码错误?如果必须添加例如,这更容易更改IsDirty标志? 当在很多情况下可能存在自定义变化时,宏没有那么有用。 像任何工具一样,宏可能会被滥用,甚至在不正确的人手中也可能很危险。对于某些程序员来说,这是一个宗教问题,一种方法优于另一种方法的优点是无关紧要的。如果是这样,则应避免使用宏。对于我们这些经常,熟练且安全地使用极为锋利的工具的人来说,宏不仅可以在编码时立即提高生产率,而且在调试和维护过程中也可以下游提高生产率。 反对为C#构建预处理程序的主要论点是在Visual Studio中进行集成:要想获得智能感知和使新的背景编译无缝地工作,将需要付出很多努力(如果可能的话)。
替代方法是使用Visual Studio生产力插件,例如ReSharper或CodeRush。
可以帮助您解决所指问题的确切类型的另一件事是诸如PostSharp之类的AOP框架。 我认为您在实现INotifyPropertyChanged时可能会丢失问题的一个重要部分。您的消费者需要一种确定属性名称的方法。因此,您应该将属性名称定义为常量或静态只读字符串,这样,使用者就不必"猜测"属性名称。如果使用预处理器,那么消费者将如何知道该属性的字符串名称是什么?
要获取当前执行的方法的名称,可以查看堆栈跟踪:
当您使用属性设置方法时,名称为set_Property。 使用相同的技术,您还可以查询源文件和行/列信息。 但是,我没有对此进行基准测试,因此为每个属性集创建一次stacktrace对象可能会非常耗时。 至少对于所提供的方案,有一个比构建预处理器更干净,类型安全的解决方案: 使用泛型。像这样:
可以很容易地扩展它以返回
由于它是
(我知道这是一个老问题,但我发现它缺乏实用的解决方案。)
有趣。我并不是真的认为预处理器一定会以这种方式工作。在提供的示例中,我正在做一个简单的文本替换,这与Wikipedia上预处理器的定义一致。 如果这不是预处理器的正确使用,那么我们应该怎么称呼简单的文本替换,通常需要在编译之前进行? 如果要设计C#的下一个版本,我会考虑每个函数都有一个自动包含的局部变量,该局部变量包含类的名称和函数的名称。在大多数情况下,编译器的优化器会将其删除。 我不确定这种事情有很多需求。 如果您准备放弃C#,则可能想看看Boo语言,该语言通过AST(抽象语法树)操作具有非常灵活的宏支持。如果您可以放弃C#语言,那就真的很棒。 有关Boo的更多信息,请参见以下相关问题:
|
最新内容
相关内容
linux指令中的命令?
linux指令中的命令?,系统,基础,工作,地址,命令,工具,管理,信息,网络,控制台,Linux系统基础操作指令linux常用命令有pwd命令、cd命令、ls命令、linux改语言命令行?
linux改语言命令行?,系统,环境,工具,密码,概念,地方,软件,通信,管理,国际,linux命令行下怎样改变语言将内容改为:LANG=zh_CN.UTF-8LANGUAGE=zh_linux命令行c语言?
linux命令行c语言?,代码,系统,工具,环境,工作,保险,发行,命令,文件,终端,linux终端下如何进行C语言编译1、在Linux下面,如果要编译一个C语言源linux命令行指令大全?
linux命令行指令大全?,工作,地址,系统,信息,命令,目录,工具,管理,基础,控制台,linux系统常用操作命令1、linux常用命令有pwd命令、cd命令、lslinux编写c语言命令?
linux编写c语言命令?,系统,基础,环境,代码,盘面,保险,百度,情况,数据,工具,在Linux系统中,如何运行一个C语言程序?编译。由.c文件生成.o文件,写linux退出指令命令?
linux退出指令命令?,档案,状态,时间,命令,系统,编辑,文件,模式,指令,内容,linux保存退出命令1、linux保存退出命令的方法如下:wq命令。不管内容linux维护网络命令?
linux维护网络命令?,网络,地址,系统,工具,信息,服务,电脑,初级,设备,命令,linux查找网络配置命令是什么?1、首先在电脑上打开Linux系统,然后进linux命令下ll指令?
linux命令下ll指令?,系统,信息,时间,标准,命令,位置,状态,单位,文件,别名,linux里的文件,如何设置为只读权限文件1、可以使用chmodfilename改linux服务器命令指令?
linux服务器命令指令?,系统,信息,工作,情况,标准,设备,对比,命令,状态,平均,16个不可不知的Linux服务器监控命令uptime 该命令直观的显示了服linux查看指令命令?
linux查看指令命令?,工作,地址,系统,网络,信息,命令,标准,中心,管理,名称,linux常用命令linux常用命令:查看内核版本:uname-a。图形界面:init5或linux常用命令行指令?
linux常用命令行指令?,工作,地址,系统,信息,管理,命令,目录,标准,控制台,文件,Linux命令有哪些?Linux常用命令大全1、linux系统常用操作命令如linux改变语言命令?
linux改变语言命令?,系统,管理,网上,官方网站,情况,服务,中文,语言,命令,终端,linux命令行下怎样改变语言将内容改为:LANG=zh_CN.UTF-8LANGUAGE