起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 3117|回复: 17

[分享]平台与Delphi.Net语言或者Borland Delphi 语言的差异

[复制链接]
发表于 2004-12-28 17:11:59 | 显示全部楼层 |阅读模式
1、不支持指针
指针(Pointer)是包含内存地址的变量。在Delphi语言中,使用Pointer作为通用指针,也称为无类型指针,另外还支持类型指针。因为指针是比较底层的技术,可以直接访问内存地址,使用不当极容易出错,另外在Delphi中使用指针也是很麻烦的(比如指针定义、内存的分配和回收),所以在Delphi.Net语言中没有提供对指针的支持。

2、过程和函数不支持缺省参数值
在Delphi中,可以通过在参数类型后面跟一个等号和它的缺省值,来声明包含缺省值参数的过程和函数,比如:
procedure HasDefVal(S: string; I: Integer = 0);
在Delphi中,对于上面定义的过程,可以按两种方式调用HasDefVal。第一种方法指定所有参数:
HasDefVal(‘hello’, 26);
第二种方法:可以传入S参数,而对参数I使用缺省值:
HasDefVal(‘Hello’);
在Delphi.Net语言中,对于缺省参数值的过程和函数定义没有做限制,但是调用时必须指定所有参数。即在Delphi.Net中,如下定义编译不会报错:
procedure HasDefVal(S: string; I: Integer = 0);
但是调用时只能使用指定所有参数的一种方法,否则编译时会报参数不匹配错误,如:
HasDefVal(‘hello’, 26); //正确调用方式
HasDefVal(‘Hello’); //错误调用方式,编译时会报错

3、不支持接口
在Delphi中,接口(Interface)定义了一系列函数和过程,可以把它理解成为某种协约,而接口的实现需要类来完成的。在Delphi中接口的一个重要应用是与COM相协调。在Delphi.Net中不能直接使用COM对象,所以没有对接口提供支持。

4、不支持静态数组
在Delphi中可以声明静态数组,即在声明时数组的大小已经确定,如下:
var
  A: Array[0..7] of Integer;
但是,在Delphi.Net语言中没有支持静态数组,即不能按以上方式声明数组,只能使用动态数组。有关Delphi.Net语言中数组的使用,请参考2.5.6 节。

5、不支持声明记录(Record)类型,但可以使用引入的记录类型
在Delphi语言中,记录(Record)是用户自定义的结构,它等同于C语言的struct。在Delphi.Net语言中不支持记录类型的声明,但是可以使用引入的记录类型,例如系统提供出来的接口方法的参数或返回值、某些Win32 API函数的参数。使用时直接声明一个对应类型的变量即可。

6、对变体类型的支持
在Delphi.Net语言中,对于变体类型不支持以下几种操作:
不支持隐式类型转换,如:
var
  V: Variant;
  D: Double;
begin
  V := 1.6;
  D := V; //编译报不能转换错误
end;
不直接支持表达式,如:
var
  V1, V2, V3: Variant;
begin
  V1 := 100;
  V2 := 50;
  V3 := 200;
  V1 := V1 + V2 + V3; //编译报不能进行+操作错误
end;
不区分Empty和Null类型;
不支持变体类型数组。

7、不支持货币类型
在Delphi.Net语言中不支持Delphi语言中的货币类型(Currency)。

8、interface和implementation
在Delphi语言中,在interface部分声明的类型、常量、变量、过程和函数,可以被其它单元共享。而在implementation部分声明的常量和变量,其它单元是无法访问的。但是在Delphi.Net中,没有这个差别,两个部分声明的常量和变量都只能在单元内部使用。

9、不支持单元的initialization和finalization部分
在Delphi中的单元中包括两个可选项:
initialization部分-位于单元底部,包括此单元的一些初始化代码。这些代码在主程序开始执行之前执行,并且只执行一次。
finalization部分-位于单元底部,放在initialization部分和单元的end之间。里面可以放入程序结束时的清除代码。
在Delphi.Net中没有支持单元的这两个部分。

10、不支持Published保留字
在Delphi中Published保留字用来表示对象中发布的属性,Delphi会为对象的Published部分生成运行时刻类型信息(RTTI,Runtime Type Information)。在Delphi.Net中不支持获取对象运行时刻信息,因此也没有对Published保留字做支持。
       
11、不支持Class方法
在Delphi语言中,Class方法是一个对类而不是对象进行操作的方法,它不同于构造函数。Class方法可以通过类引用或对象引用来调用。在Delphi.Net中没有支持Class方法。

12、支持静态方法
在Delphi.Net中支持了类似于C++中的静态方法,静态方法是对类的,可以直接通过类名来调用静态方法,在Delphi.Net中使用static保留字来声明和定义静态方法。如下示例:
type
  TMyObject = clase
   public
     static procedure StaticPro; //声明静态方法
  end;
//静态方法定义
static procedure TMyObject.Staticpro;
begin
  …
end;
//调用静态方法
TMyObject.Staticpro;

13、不支持强类型别名
在Delphi中可以为已知类型创建一个新名称,或称作别名(alias)。比如,打算给Integer取别名MyInteger,我们可以按下面代码去做:
type
  MyInteger = Integer;
新定义的别名类型等同于原始类型,因此,在上例中,我们可以将MyInteger用在任何以前使用Integer的场合。
另外,在Delphi中还可以定义强类型(strongly typed)别名,编译器把强类型别名当作新的而且独一无二的类型。在Delphi中,强类型的声明中使用type保留字,如下:
type
  MyInteger = type Integer;
在Delphi.Net语言中,也同样提供了类型别名的定义和使用,但是对于强类型别名没有支持。即在Delphi.Net语言中如下定义是错误的:
type
  MyInteger = type Integer;

14、不支持字符串资源保留字resourcestring
在Delphi中,可以使用resourcestring字句直接把字符串资源放入到Delphi代码中。在Delphi.Net语言中不支持此保留字的使用。

15、不支持获取运行时信息
在Delphi中,通过运行时信息(RTTI,Runtime Type Information)可以在运行时刻取得Delphi应用程序中对象的信息,比如对象的类名、父类等。在Delphi.Net中不支持对运行时信息的获取,所以也就无法在运行时得到对象的类名等信息。

16、不支持goto语句
goto语句也称为无条件跳转语句,使用goto语句会使代码的阅读和维护变得更加困难。另外,在50-60年代的软件危机中,经过统计,发现大量的错误出现在goto语句上。所以人们提出限制使用goto语句,因此在Delphi.Net语言中,从语言上就没有支持goto语句,从而避免了goto语句的不当使用造成的错误。

17、不支持PChar类型为返回值的WindowsAPI
在Delphi中,PChar类型主要用于兼容Win32,把PChar定位成后面以null(#0)结尾的字符串指针。在Delphi.Net语言中,对于WindowsAPI中PChar类型参数的使用是由一定限制的。
当WindowsAPI中传入参数是PChar类型时,可以直接使用string类型变量值,但是当以PChar类型作为返回值时(注意,在系统中的WindowsAPI中所有PChar类型都被包装成了string类型,所以看到的是string类型),在Delphi.Net中没有支持。相关介绍,请参考2.5.5 节。

18、使用枚举值的特殊性,要带上枚举类型名
在Delphi.Net语言中使用枚举值时,需要带上枚举类型名,如下代码:
type
TShiftStateEnum = (ssShift, ssAlt, ssCtrl,ssLeft, ssRight, ssMiddle, ssDouble);
……
var
  lShiftState: TShiftStateEnum;
begin
  lShiftState := TShiftStateEnum.ssAlt;
end;

19、集合类型的限制
在Delphi.Net语言中集合类型只能以如下方式定义,即set of后面跟枚举类型,如:
TEnum = (Monday, Tuesday, Wednesday, Thursday, Friday);
TEnumSet = set of TEnum;

另外,Delphi.Net语言中的集合只能容纳64个元素。在内部,集合是把元素按单独的位存储的,集合中只能是序数类型,这使得超过64的序数值无法存储到集合中。如下代码将编译不过:
if c in ['a', 'b', 'c'] then
  …
这是因为Ord('a') > 90,超过了64,所以无法存储到集合。

20、不支持全局变量、常量、函数
在Delphi.Net语言中不支持全局的变量、常量和函数。但是在Delphi.Net语言中有单元变量、常量和函数的概念,即这些变量、常量和函数在定义它的整个单元内部是可见的。对于Delphi中的全局变量、常量,我们可以用另外一种方式来实现:创建一个公共的单元,在单元内部定义单元变量和常量,然后在单元的类中以静态方法来访问这些变量和常量,这样就可以在其它使用到这些常量和变量的地方引入该公共单元,从而达到Delphi中全局变量和常量的作用。另外,全局的函数可以直接以定义类的静态方法的方式来实现。

21、程序集和命名空间
在Delphi.Net中有程序集(Assmbly)和命名空间的概念。程序集是包含编译好的、面向.Net的代码的逻辑单元。命名空间是.Net避免类名冲突的一种方式,命名空间中所有数据类型的名称都会自动加上一个该命名空间的名字作为前缀。在Delphi.Net中,每个程序集都对应一个命名空间。另外,在Delphi.Net单元中的use子句中包含的是命名空间,而不像Delphi中是单元名。

22、不需要 forward declare
在Delphi中的forward declare是指:在程序中使用一种类型时,该类型必须在使用它的代码行之前已经声明过。如下代码在Delphi中将编译不通过:
TMyClass1 = class
private
  FC: TMyClass2; //编译时会报没有声明TMyClass2错
  ...
end;
TMyClass2 = class
...
end;
在Delphi.Net语言中则没有这种限制,不会对类型声明的顺序做要求。

23、不支持类类型(class of)
在Delphi语言中有类类型的定义,如下代码:
type TClass = class of TObject;
var AnyObj: TClass;
其中AnyObj变量可以是任何类的一个引用。在Delphi.Net中则不支持类类型的定义。

24、属性声明的差异
在Delphi语言中,属性声明的句法如下所示:
property PropertyName[indexes]: type index integerConstant specifiers;
这里,PropertyName可以是任何有效的标识符;[indexes]是一个由分号分隔的参数声明序列,它是可选的;index integerConstant子句也是可选的;specifiers则是一个read、write、stored、default(nondefault)和implements说明符。
而在Delphi.Net语言中的属性声明句法为:
property PropertyName[indexes]: type specifiers;
其中不支持index integerConstant子句,并且specifiers说明符只支持read和write。
回复

使用道具 举报

 楼主| 发表于 2004-12-28 17:12:58 | 显示全部楼层

平台与Delphi.Net语言或者Borland Delphi.Net 语言的差异

1、不支持static private和static protected

2、不支持class var

3、不支持静态成员属性static property

4、不支持静态构造函数static constructor

5、不支持Sealed Classes

6、不支持嵌套类型(Nested Type)

7、不支持操作符重载(Operator Overload)

8、不支持class helper
回复 支持 反对

使用道具 举报

发表于 2005-1-24 12:12:05 | 显示全部楼层
不支持子程序嵌套
回复 支持 反对

使用道具 举报

发表于 2005-1-25 14:30:53 | 显示全部楼层
不支持Class方法

可以通过静态的方法来实现同样的效果
回复 支持 反对

使用道具 举报

发表于 2005-1-25 14:37:14 | 显示全部楼层

集合的限制

Delphi.Net语言中的集合只能容纳64个元素。在内部,集合是把元素按单独的位存储的,集合中只能是序数类型,这使得超过64的序数值无法存储到集合中。如下代码将编译不过:
if c in ['a', 'b', 'c'] then
  …
这是因为Ord('a') > 90,超过了64,所以无法存储到集合。

可以通过如下方法实现: if (c ='a') or (c='b') or (c='c') then
回复 支持 反对

使用道具 举报

发表于 2005-1-25 14:38:44 | 显示全部楼层

不支持指针

Business 平台目前不支持指针类型变量。Business 平台编译是严格按照.net中间语言的规范来做的,和C#、java一样,已经没有指针和结构体了,直接写一个类来代替。

例如:直接定义一个类

TNav = class(object)
  A: string;
  B: Integer;
  C: string;
end;
回复 支持 反对

使用道具 举报

发表于 2005-1-25 14:42:21 | 显示全部楼层

不支持静态数组

只能运用动态数组

例如:

var
   f: array of Integer;
   i: integer;
begin
SetLength(f,9);
   for i:=0 to length(f)-1 do
   begin
  //....
   end;
end;

在Delphi.Net语言中可以创建任何变量类型的数组(文件类型除外),另外需要说明的是:Delphi.Net语言只支持动态数组。动态数组是编译期间维数不能确定的数组。声明动态数组如下所示:
var
  SA: array of string;
在使用动态数组前,必须使用SetLength()函数给数组分配内存:
begin
  SetLength(SA, 33);
end;
一旦分配了内存以后,就可以使用索引来访问数组:
SA[0] := ‘string1’;
在Delphi.Net语言中数组的索引总是从0开始,如SA的索引就是从0到32。当按索引对数组进行访问的时候,需要小心处理数组的边界。编译器提供了内建的函数High()和Low(),这两个函数分别返回数组变量的索引上限和下限值。在循环中用这两个函数做边界控制会时程序易于维护不容易出错,见下面代码:
var
  I: Integer;
  A: array of Integer;
begin
  SetLength(A, 10);
  for I := Low(A) to High(A) do
    A[I] := I;
end;
动态数组是生存期管理类型,因此我们用完了之后可以不需要手动释放内存,Delphi.Net会在动态数组超出作用域后释放掉动态数组。然而,在某些场合,可能需要在动态数组未超出作用域时提前释放掉它们(例如在动态数组占用了大量内存的场合),这种情况下我们只需使用SetLength()函数把动态数组长度设置为0:
SetLength(A, 0);
下面看一段关于数组的引用操作的代码,执行完毕后,A1[0]值是什么?
var
  A1, A2: array of Integer;
begin
  SetLength(A1, 10);
  A2 := A1;
  A1[0] := 1;
  A2[0] := 26;
end;
正确答案是26。因为赋值表达式A2 := A1并没有创建新的数组,而是A2引用A1,或者说A2指向A1。因此,对A2的任何操作都会影响到A1。如果我们希望把A1内容完全复制给A2,要使用数组变量的CopyTo()方法:
SetLength(A2, 10);
A1.CopyTo(A2, 0);

在Delphi.Ne语言中,不支持多维数组
回复 支持 反对

使用道具 举报

发表于 2005-1-25 14:46:22 | 显示全部楼层

对变体类型的支持

设计变体类型的主要目的之一是给我们提供一种变量,这种变量的数据类型可能在运行时刻有所改变,因此在编译时刻难以决定它的数据类型。这意味着变体类型可以在运行时刻,按照引用的数据类型的不同而改变自己的数据类型。例如,下面的代码能够编译通过,并正确运行:
var
  V: Variant;
begin
  V := 'Delphi.Net';
  V := 1;
  V := 123.34;
  V := True;
end;
变体类型支持所有简单数据类型,比如整数、浮点数、字符串、布尔值和日期时间变量。注意变体类型不能引用Delphi.Net对象。Delphi.Net自动分配和释放Variant变量所需的内存。
类型转换
可以把变体类型强制转换成简单数据类型。例如下面的赋值:
V := 1.6;
这里V是Variant类型的变量,下面的表达式会对V进行转换:
I := Integer(V); //返回I值不确定
B := Boolean(V); //如果V是0,则B为False;否则B为True
D := Double(V); //D为1.6
在对变体类型进行强制转换时,最好能确定某个变体类型对应的数据类型,然后进行显示类型转换,否则转换结果有些是不确定的,比如上例中的I := Integer(V)表达式其结果就不是我们想要的一个整数。另外对应字符串和日期时间型数据的转换,需要如下调用:
S := Variants.VarToStr(V); //转换为字符串
DT := Variants.VarToDateTime(V); //转换为日期时间

在Delphi.Net语言中,对于变体类型不支持以下几种操作:
不支持隐式类型转换,如:
var
  V: Variant;
  D: Double;
begin
  V := 1.6;
  D := V; //编译报不能转换错误
end;
不直接支持表达式,如:
var
  V1, V2, V3: Variant;
begin
  V1 := 100;
  V2 := 50;
  V3 := 200;
  V1 := V1 + V2 + V3; //编译报不能进行+操作错误
end;
回复 支持 反对

使用道具 举报

发表于 2005-1-25 14:50:18 | 显示全部楼层

不支持goto语句

Business平台不支持Goto语句,任何的goto语句都可以转换为标准的if while repeat语句来实现的。
回复 支持 反对

使用道具 举报

发表于 2005-1-25 15:03:05 | 显示全部楼层

过程和函数不支持缺省参数值

可以通过方法重载来实现

procedure HasDefVal(S: string);override;
var
I:integer;
begin
I:=26;
HasDefVal(‘Hello’,I);
end;
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2024-4-24 14:59 , Processed in 0.048019 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表