【转贴】在BCB中实现类C#属性声明语法

转载 2004年09月07日 23:41:00
 
【转贴】goldroc的专栏在BCB中实现类C#属性声明语法
巧用宏命令,改造BCB——在BCB中实现类C#属性声明语法
引子

 余好程序,喜BCBBorland C Builder。一日见C#之属性声明,顿觉清爽。其后偶有所启,遂整以条理、载以文字,且冠文章之名。
于夫同好而喜BCB者,或可有益。若是,其旨达矣。 背景描述——宏的历史地位 面向对象的C语言推出后,曾经在C中极其重要的宏命令似乎变得很少使用了。连C大师Bjarne Stroustrup在他的经典C教程
《The C Programming Language》中也如是说:“关于宏的第一项规则是:绝对不应该去使用它,除非你不得不这样做。因为它将在
编译器看到程序的正文之前重新摆布这些正文。” 就连以前用的最多的定义常量在C中也有了新关键字了,在加上其他的
机制等都是为了用做预处理结构的许多传统使用方式的替代品。 不过,Bjarne Stroustrup自己也承认,利用宏我们可以设计出自己的私有语言。只要它能让我们的工作简化,那它就是一个有用的宏。 “可以设计出自己的私有语言”,这对于我们而言意味着什么?又如何使用它来好好改造现有的语言,以便简化我们的工作呢?当然,所谓
简化必然是对繁杂而言。那么只要是原有的语法显得繁杂的地方我们都可以使用宏来简化它。 一个很好的典型就是BCB中的属性声明语法。 背景描述——BCB和C#的属性声明语法 要在BCB的类声明中声明一个属性,首先必须声明一个属性数据的存放者——一个数据成员。当然一般而言是在私有部分声明的。然后如果在
读或写属性时还有一些其他的操作,那就得声明读或写属性的方法。一般来讲为了保证数据的合法行,往往至少需要一个写属性方法。最后还
得在或__publish(组件用)中发布出来,才能被类的使用者可见。 还是来看看具体的代码吧。 假设一个女孩类CGirl,有个漂亮指数属性Prettiness,并且取值范围是:其丑无比;:马马虎虎;:相貌端庄:倾国倾城。那
么在BC中大抵都得这么写: 头文件CGirlh中 CGirl __property PrettinessreadFGetPrettinesswriteFSetPrettiness FPrettiness __fastcall FGetPrettiness __fastcall FSetPrettiness vPrettiness 代码文件CGirlcpp中 __fastcall CGirl FGetPrettiness FPrettiness __fastcall CGirl FSetPrettiness vPrettiness vPrettiness vPrettiness FPrettinessv FPrettiness …… 对于简单的类,这样的定义也许还不算太麻烦。属性的声明定义还能一目了然。但如果类稍微复杂一点——具体一点如果是一个行的类呢?
(冒汗)
结果往往是在诺大的代码里翻来翻去,为的就是查看和某个属性相关的读或写方法的定义。 而现在,在微软Net的发布后,Net Framework一下子成了最流行的东东。它以不可阻挡之势袭来。而且微软为了和SUN的Java争个高下,
也不顾现在编程语言的泛滥之势,在Visual Studio中又加入了一种新的语言。我想不用我说大家早就知道了——对就是它:C#,又一个和
C语法十分相似的语言。 对于Net和C#的故事实在太多了,不可能也不需要在这里说了。但是C#的对于属性声明的语法却给笔者留下了深刻的影响。这恰恰也正是今
天我们所关心的。那么来看看C#的属性声明语法吧。同样以上面的CGirl类作为例子,用C#写来可能是下面这个样子: CGirl FPrettiness Prettiness get FPrettiness set value value FPrettinessvalue 不用我多说,孰繁孰简已经很明显了。 下面,我们就来动手看看如何通过宏命令把BCB繁杂的属性声明语法变的一如C#般简洁。这不是变戏法但其精彩却一点也不亚于它。 技术基础——宏定义语法 首先,我们得了解宏的定义格式:#define宏名展开内容 其实这样的东西几乎是什么都不能做的,但要是给它带上参数就不一样了: 比如一个带参宏的声明:#define WRITENa coutaendl 在代码中假如这么写:WRITEN 那么,其经过宏扩展后就会变成这样:coutendl 这就是带参宏的扩展规律了,并不复杂。为了要把BCB的属性声明语法变成C#,我们另外还需要知道两个操作符: 和 ## 。 操作符:当宏定义的扩展内容不止一行时的连接符。 要换行写宏定义的话,在行尾加上它就行了。如: 就等效于: 、## 操作符:参数扩展连接符。 它可以把前面的内容和参数连接成一个没有间隔的整体。还是来看看例子: 定义一个宏: #define VARi ji##j 那么如果在代码中这样写:VARx ,它将会被扩展为x6。利用这个特性我们就可以对给定的宏参数加以修饰,以便适应我们的要求了。 技术实现——开始改造BCB 基础的东西就这么多了,那就来看看需要怎么做来改造BCB。 首先,确定宏的名称,这里暂时就以PROPERTY为宏名。 其次,确定宏的参数。 我们的目的要使宏使用起来和C#的语法尽量相似,那么宏使用起来多少应该像这样: PROPERTY 属性的可见性 属性类型 属性名 get set 但上面这样的伪代码虽然最接近C#语法,却无法定义出适合的宏。原因是宏所需要的一些重要的参数元素无法从整体的代码中分隔出来。
所谓重要的参数元素就是上面伪代码中描述的 “属性的可见性”、“属性类型”、“元素名”、“读属性代码部分”以及“写属性部分”
这些东西。而上面伪代码中从“属性的可见性”开始一直到最后一个大括号是一个整体,成为一个参数。这自然无法正确扩展了。我们
应该把这五个重要的元素分开为一个个的参数,原则当然是和上面的伪代码形式越相似越好: PROPERTY 属性的可见性 属性类型 属性名 get set 这样就形式上而言达到了把每个元素分开而独立成为一个宏参数的要求。 然后,就上面的使用形式,我们来设计这个宏。 先给上面的每个元素取个标识,分别是: 属性的可见性 pRegion 属性类型 pType 属性名 pName 读属性代码 pGetMethod 写属性代码 pSetMethod 还记得在BCB声明一个属性需要的两个方法函数吗,分别对应读和写。在宏定义里必须采用固定的函数名,而且必须和属性名相关。
这样我们定为在属性名前分别加FGet和FSet来构成读写方法函数名,其中写方法的参数(对应属性的新值)始终是value(一如在C#中)。 在宏中的定义: pType __fastcal FGet##pName pGetMethod __fastcall FSet##pNamepType value pSetMethod 别忘了还有一个属性发布语句: __property pType pNameread FGet##pNamewrite FSet##pName 整理一下,宏的声明最后变成下面这样: PROPERTYpRegionpTypepNamepGetMethodpSetMethod pType FGet##pName pGetMethod FSet##pNamepType value pSetMethod pRegion __property pType pName readFGet ##pNamewriteFSet ##pName 请注意:在宏的使用代码中,读或写方法函数还有get或set标识符,而它们必须被屏蔽,否则无法通过把pGetMethod或pSetMethod
附加在函数声明后而形成完整的函数实现。 通过下面的两句宏声明来屏蔽get或set: 到这里,这个宏定义就算基本成功了。然而,由于属性可能有只读的、只写的或不需要读方法函数的(很多属性只要直接读取成员数据
的值就可以了,不需要额外的代码)种类区别,我们还需要另外几个可以适用于这些情况的宏。参看具体代码。 最后,使用这样的宏有几个值得特别注意的地方: 、注意分隔各个宏参数的逗号,特别是get和set方法之间的不能漏掉。 、注意get和set方法实现不能颠倒位置。 完整实现——具体的代码 (以上代码在BCB6中调试通过) 这样,把以上代码保存为一个头文件,如property_macroh。以后在自己的代码中#include包含进这个头文件即可。
根据同样的原理,我们甚至可以把BCB的整个类声明语法都改造成类C#的,这里不再累述了,读者可以自己动手试试。 现在,让我们来尝尝在BCB中写“C#”的感觉吧。

C#中的‘集合’案例

-
  • 1970年01月01日 08:00

巧用宏命令,改造BCB——在BCB中实现类C#属性声明语法

巧用宏命令,改造BCB ——在BCB中实现类C#属性声明语法  goldroc引子 余好程序,喜BCB(Borland C++ Builder)。一日见C#之属性声明,顿觉清爽。其后偶有所启,遂整以条...
  • goldroc
  • goldroc
  • 2004-09-07 21:32:00
  • 1507

SpringFramework学习-(9)基于注解配置bean

前面几篇文章介绍了基于配置文件的bean的配置,Spring还提供基于注解形式来配置bean。 Spring提供了组件扫描(component scanning),能够从classpath下自动扫描...
  • jinjin603
  • jinjin603
  • 2017-12-28 23:20:46
  • 32

Delphi和BCB中属性设置问题

BCB里面的属性,改变它们的值时,大多数情况下都需要调用相关的函数。比如这儿: __property TButtonSet VisibleButtons = {read=FVisibleButto...
  • lcfeng1982
  • lcfeng1982
  • 2012-10-27 10:27:02
  • 1616

C#语法:委托与方法

1、了解委托(delegate) * 委托是一种全新的面向对象语言特性,运行于.NET平台     *基于委托开发事件驱动程序变得简单 *使用委托可以大大简化多线程编程的难度 2、理解委托 *委托(d...
  • superSmart_Dong
  • superSmart_Dong
  • 2017-06-01 13:36:54
  • 560

Objective-C(四、属性声明与功能,点语法)——iOS开发基础

点语法;属性声明与实现@property和@synthesize; 实例变量的可见性,作用域@private,@protected,@public,@package; 属性指定选项:assign,re...
  • Zsk_Zane
  • Zsk_Zane
  • 2015-06-26 12:55:30
  • 1614

C#中一些默认的预定义属性

C#中一些默认的预定义属性,见下表: 预定义的属性 有效目标 说明 AttributeUsage Class 指定另一个属性类的有效使用方式 CLSCompliant 全部 指出程序元素是否与CLS兼...
  • su317
  • su317
  • 2007-12-28 11:15:00
  • 585

【Unity3D】Unity3D中的C#基本语法知识点①(变量与数组)

【本文为囧希博客个人原创文章,转载请注明出处!http://blog.csdn.net/yunpro】 【变量】 Unity中变量声明如下: string player = "abcdef"...
  • YunPro
  • YunPro
  • 2015-03-02 22:43:09
  • 753

【c#】定义类成员(字段、方法、属性)

成员定义 public----成员可以由任何代码访问private----成员只能由类中的代码访问(如果没有使用任何关键字,默认使用这个关键字)internal----成员定只能由义他的...
  • qq_30594349
  • qq_30594349
  • 2017-07-16 22:15:51
  • 691

XML__XML文档声明<? ... ?>中的standalone属性

standalone在XML里的作用  今天在看用TdataSet生成的XML中第一行里有个standalone,不知道是什么意思,查了一下资料才知道它的作用,下面就把我了解的写下来。    ...
  • u010003835
  • u010003835
  • 2015-11-12 16:21:19
  • 3143
收藏助手
不良信息举报
您举报文章:【转贴】在BCB中实现类C#属性声明语法
举报原因:
原因补充:

(最多只允许输入30个字)