DELPHI and C# Comparison
DELPHI7與C#語法比較
編制:黃煥堯 參考:VB.net and C# Comparison 日期:2005-5-30.
Comments 注釋
Data Types數據類
Constants 常量
Enumerations 枚舉
Operators 運算
Choices 選擇語句
Loops 循環語句
Arrays 數組
Functions 函數
Exception Handling 異常處理
Namespaces 命名空間
Classes / InterfacesConstructors / Destructors 構造/釋構
Objects 對象
Structs 結構
Properties 屬性
Delegates / EventsConsole I/OFile I/ODELPHI
C#
Comments注釋
// Single line only
{ Multiple
line }
(* Multiple
line *)
// Single line
/* Multiple
line */
/// XML comments on single line
/** XML comments on multiple lines */
Data Types 數據類型
Value Types 簡單類型
Boolean
Byte
Char (example: "A"c)
Word, Integer, Int64
Real ,Single, Double,Real48,Extended,Comp,Currency
Decimal
Tdate,TDateTime
Reference Types
Object
String(ShortString,AnsiString,WideString)
Set, array, record, file,class,class reference,interface
pointer, procedural, variant
var x:Integer;
WriteLine(x); // Prints System.Int32
WriteLine(‘Ingeger’); // Prints Integer
// Type conversion
var numDecimal:Single = 3.5 ;
var numInt:Integer;
numInt :=Integer(numDecimal) // set to 4 (Banker‘s rounding)
the decimal)
Value Types
bool
byte, sbyte
char (example: ‘A‘)
short, ushort, int, uint, long, ulong
float, double
decimal
DateTime (not a built-in C# type)
Reference Types
object
string
int x;
Console.WriteLine(x.GetType()); // Prints System.Int32
Console.WriteLine(typeof(int)); // Prints System.Int32
// Type conversion
double numDecimal = 3.5;
int numInt = (int) numDecimal; // set to 3 (truncates decimal)
Constants常量
Const MAX_STUDENTS:Integer = 25;
const int MAX_STUDENTS = 25;
Enumerations枚舉
Type Taction1=(Start, Stop, Rewind, Forward);
{$M+}
Type Status=(Flunk = 50, Pass = 70, Excel = 90);
{$M-}
var a:Taction1 = Stop;
If a <>Start Then WriteLn(ord(a)); // Prints 1
WriteLine(Ord(Pass)); // Prints 70
WriteLine(GetEnumName(TypeInfo(Status),Ord(Pass))); // Prints Pass
ShowEnum(Pass); //outputs 70
GetEnumValue(GetEnumName(TypeInfo(Status),’Pass’));//70
enum Action {Start, Stop, Rewind, Forward};
enum Status {Flunk = 50, Pass = 70, Excel = 90};
Action a = Action.Stop;
if (a != Action.Start)
Console.WriteLine(a + " is " + (int) a); // Prints "Stop is 1"
Console.WriteLine(Status.Pass); // Prints Pass
Operators運算符
Comparison 比較
= < > <= >= <> in as
Arithmetic 算述述運算
+ - * / div
Mod
\ (integer division)
^ (raise to a power) 階乘
Assignment 賦值分配
:= Inc() Dec() shl shr
Bitwise 位運算
and xor or not shl shr
//Logical
and xor or not
//String Concatenation
+
Comparison
== < > <= >= !=
Arithmetic
+ - * /
% (mod)
/ (integer division if both operands are ints)
Math.Pow(x, y)
Assignment
= += -= *= /= %= &= |= ^= <<= >>= ++ --
Bitwise
& | ^ ~ << >>
Logical
&& || !
Note: && and || perform short-circuit logical evaluations
String Concatenation
+
Choices 判斷
greeting := IfThen (age < 20, ‘What‘s up?’, ‘Hello’);
If language = ‘DELPHI’ Then
langType := ‘hymnlan’;
//
If x <> 100 Then
begin
x := x*5 ; y :=x* 2;
end;
// or to break up any long single command use _
If (whenYouHaveAReally < longLine
and itNeedsToBeBrokenInto2 > Lines Then
UseTheUnderscore(charToBreakItUp);
‘If x > 5 Then
x :=x* y
Else If x = 5 Then
x :=x+ y
Else If x < 10 Then
x :=x- y
Else
x :=x/ y ;
Case color of // 不能為字符串類型
pink, red:
r :=r+ 1;
blue:
b :=b+1;
green:
g :=g+ 1;
Else
Inc(other);
End;
greeting = age < 20 ? "What‘s up?" : "Hello";
if (x != 100) { // Multiple statements must be enclosed in {}
x *= 5;
y *= 2;
}
No need for _ or : since ; is used to terminate each statement.
if (x > 5)
x *= y;
else if (x == 5)
x += y;
else if (x < 10)
x -= y;
else
x /= y;
switch (color) { // Must be integer or string
case "pink":
case "red": r++; break; // break is mandatory; no fall-through
case "blue": b++; break;
case "green": g++; break;
default: other++; break; // break necessary on default
}
Loops 循環
Pre-test Loops:
While c < 10 do
Inc(c) ;
End
For c = 2 To 10 do
WriteLn(IntToStr(c));
For c = 10 DownTo 2 do
WriteLn(IntToStr(c));
repeat
Inc(c);
Until c = 10 ;
// Array or collection looping
count names:array[] of String = (‘Fred’, ‘Sue’, ‘Barney’)
For i:=low(name) to High(name) do
WriteLn(name[i]);
DELPHI8開始支持 for … each … 語法
Pre-test Loops:
// no "until" keyword
while (i < 10)
i++;
for (i = 2; i < = 10; i += 2)
Console.WriteLine(i);
Post-test Loop:
do
i++;
while (i < 10);
// Array or collection looping
string[] names = {"Fred", "Sue", "Barney"};
foreach (string s in names)
Console.WriteLine(s);
Arrays 數組
var nums:array[] of Integer = (1, 2, 3)
For i := 0 To High(nums) do
WriteLn(IntToStr(nums[i]))
// 4 is the index of the last element, so it holds 5 elements
var names:array[0..5] of String; //用子界指定數組范圍
names[0] = "David"
names[5] = "Bobby"
// Resize the array, keeping the existing values
SetLength(names,6);
var twoD:array[rows-1, cols-1] of Single;
twoD[2, 0] := 4.5;
var jagged:array[] of Integer =((0,0,0,0),(0,0,0,0));
jagged[0,4] := 5;
int[] nums = {1, 2, 3};
for (int i = 0; i < nums.Length; i++)
Console.WriteLine(nums[i]);
// 5 is the size of the array
string[] names = new string[5];
names[0] = "David";
names[5] = "Bobby"; // Throws System.IndexOutOfRangeException
// C# doesn‘t can‘t dynamically resize an array. Just copy into new array.
string[] names2 = new string[7];
Array.Copy(names, names2, names.Length); // or names.CopyTo(names2, 0);
float[,] twoD = new float[rows, cols];
twoD[2,0] = 4.5f;
int[][] jagged = new int[3][] {
new int[5], new int[2], new int[3] };
jagged[0][4] = 5;
Functions函數
‘ Pass by value(傳值參數) (in, default), 傳遞引用參數reference (in/out), and reference (out)
procedure TestFunc( x:Integer, var y:Integer, var z:Integer)
;
begin
x :=x+1;
y :=y+1;
z := 5;
End;
count a = 1;
var b:integer=1; c :Integer=0; // c set to zero by default
TestFunc(a, b, c);
WriteLn(Format(‘%d %d %d’,[a, b, c]); // 1 2 5
// Accept variable number of arguments
Function Sum(nums:array[] of Integer):Integer;
begin
Result := 0;
For i:=Low(nums) to high(nums) do
Result := Result + I;
End
var total :Integer;
total := Sum(4, 3, 2, 1); // returns 10
// Optional parameters must be listed last and must have a default value
procedure SayHello( name:String;prefix:String = ‘’);
begin
WriteLn(‘Greetings, ‘ + prefix + ‘ ‘ + name);
End;
SayHello(‘Strangelove’, ‘Dr.’);
SayHello(‘Madonna’);
// Pass by value (in, default), reference (in/out), and reference (out)
void TestFunc(int x, ref int y, out int z) {
x++;
y++;
z = 5;
}
int a = 1, b = 1, c; // c doesn‘t need initializing
TestFunc(a, ref b, out c);
Console.WriteLine("{0} {1} {2}", a, b, c); // 1 2 5
// Accept variable number of arguments
int Sum(params int[] nums) {
int sum = 0;
foreach (int i in nums)
sum += i;
return sum;
}
int total = Sum(4, 3, 2, 1); // returns 10
/* C# doesn‘t support optional arguments/parameters. Just create two different versions of the same function. */
void SayHello(string name, string prefix) {
Console.WriteLine("Greetings, " + prefix + " " + name);
}
void SayHello(string name) {
SayHello(name, "");
}
Exception Handling 異常處理
‘ Deprecated unstructured error handling
var ex :TException;
ex:=TException.Create(‘Something is really wrong.’);
Try //DELPHI 不支持異常捕捉與Finally同時使用
Try
y = 0
x = 10 / y
except
ON Ex:Exception
begin
if y = 0 then ‘
WriteLn(ex.Message) ;
end;
Finally
Beep();
End;
Exception up = new Exception("Something is really wrong.");
throw up; // ha ha
try {
y = 0;
x = 10 / y;
}
catch (Exception ex) { // Argument is optional, no "When" keyword
Console.WriteLine(ex.Message);
}
finally {
// Must use unmanaged MessageBeep API function to beep
}
Namespaces 命名空間
//delphi無命名空間,以單元與之對應
Unit Harding;
...
End.
uses Harding;
namespace Harding.Compsci.Graphics {
...
}
// or
namespace Harding {
namespace Compsci {
namespace Graphics {
...
}
}
}
using Harding.Compsci.Graphics;
Classes / Interfaces 類和接口
Accessibility keywords 界定關鍵字
Public
Private
Protected
published
// Protected
Type FootballGame= Class
Protected
Competition:string;
...
End
// Interface definition
Type IalarmClock= Interface (IUnknown)
...
End // end Interface
// Extending an interface
Type IalarmClock= Interface (IUnknown)
[‘{00000115-0000-0000-C000-000000000044}‘]
function Iclock:Integer;
...
End //end Interface
// Interface implementation
Type WristWatch=Class(TObject, IAlarmClock ,ITimer)
function Iclock:Integer;
...
End
Accessibility keywords
public
private
internal
protected
protected internal
static
// Inheritance
class FootballGame : Competition {
...
}
// Interface definition
interface IAlarmClock {
...
}
// Extending an interface
interface IAlarmClock : IClock {
...
}
// Interface implementation
class WristWatch : IAlarmClock, ITimer {
...
}
Constructors / Destructors構造/釋構
Type SuperHero=Class
Private
ApowerLevel:Integer;
Public
constructor Create;override;
constructor New(powerLevel:Integer); virtual;
destructor Destroy; override;
end; //end Class Interface
Implementation
procedure Create();
begin
ApowerLevel := 0;
end;
procedure New(powerLevel:Integer);
begin
self.ApowerLevel := powerLevel;
end;
procedure Destroy;
begin
…
inherited Destroy;
end
End.
class SuperHero {
private int _powerLevel;
public SuperHero() {
_powerLevel = 0;
}
public SuperHero(int powerLevel) {
this._powerLevel= powerLevel;
}
~SuperHero() {
// Destructor code to free unmanaged resources.
// Implicitly creates a Finalize method
}
}
Objects 對象
var hero:SuperHero;
hero := SuperHero.Create;
With hero
Name := "SpamMan";
PowerLevel := 3;
End //end With
hero.Defend(‘Laura Jones’);
hero.Rest(); // Calling Shared method
// or
SuperHero.Rest();
var hero2:SuperHero;
hero2:= hero; // Both refer to same object
hero2.Name := ‘WormWoman’;
WriteLn(hero.Name) // Prints WormWoman
hero.Free;
hero = nil; // Free the object
if hero= nil then
hero := SuperHero.Create;
var obj:Object;
obj:= SuperHero.Create;
if obj is SuperHero then
WriteLn(‘Is a SuperHero object.’);
SuperHero hero = new SuperHero();
// No "With" construct
hero.Name = "SpamMan";
hero.PowerLevel = 3;
hero.Defend("Laura Jones");
SuperHero.Rest(); // Calling static method
SuperHero hero2 = hero; // Both refer to same object
hero2.Name = "WormWoman";
Console.WriteLine(hero.Name); // Prints WormWoman
hero = null ; // Free the object
if (hero == null)
hero = new SuperHero();
Object obj = new SuperHero();
if (obj is SuperHero)
Console.WriteLine("Is a SuperHero object.");
Structs記錄/結構
Type
StudentRecord = packed Record
name:String;
gpa:Single;
End //end Structure
Var stu:StudentRecord;
stu.name:=’Bob;
stu:=3.5;
var stu2:StudentRecord;
stu2 := stu;
stu2.name := ‘Sue’;
WriteLn(stu.name) // Prints Bob
WriteLn(stu2.name) // Prints Sue
struct StudentRecord {
public string name;
public float gpa;
public StudentRecord(string name, float gpa) {
this.name = name;
this.gpa = gpa;
}
}
StudentRecord stu = new StudentRecord("Bob", 3.5f);
StudentRecord stu2 = stu;
stu2.name = "Sue";
Console.WriteLine(stu.name); // Prints Bob
Console.WriteLine(stu2.name); // Prints Sue
Properties屬性
Private
Asize:Integer;
Published
Property Size:Integer read GetSize write SetSize;
End;
Implementation
Function GetSize:Integer;
begin
Result:=Asize;
end;
procedure SetSize(Value:Integer);
begin
if Value<0 then
Asize := 0
else
Asuze := Value;
end;
foo.Size := foo.Size + 1;
private int _size;
public int Size {
get {
return _size;
}
set {
if (value < 0)
_size = 0;
else
_size = value;
}
}
foo.Size++;
Delegates / Events事件
Type
MsgArrivedEventHandler=prcedure(message:string) of object;
MsgArrivedEvent:MsgArrivedEventHandler;
Type
MyButton =Class(Tbutton)
private
FClick:MsgArrivedEventHandler;
public
procedure Click;
property onClick:MsgArrivedEventHandler read Fclick write Fclick;
end;
Implementation
Procedure MyButton.Click;
begin
MessageBox (self.handle, ‘Button was clicked’, ‘Info’,
MessageBoxButtonsOK, MessageBoxIconInformation);
end;
delegate void MsgArrivedEventHandler(string message);
event MsgArrivedEventHandler MsgArrivedEvent;
// Delegates must be used with events in C#
MsgArrivedEvent += new MsgArrivedEventHandler(My_MsgArrivedEventCallback);
MsgArrivedEvent("Test message"); // Throws exception if obj is null
MsgArrivedEvent -= new MsgArrivedEventHandler(My_MsgArrivedEventCallback);
using System.Windows.Forms;
Button MyButton = new Button();
MyButton.Click += new System.EventHandler(MyButton_Click);
private void MyButton_Click(object sender, System.EventArgs e) {
MessageBox.Show(this, "Button was clicked", "Info",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
Console I/O
DELPHI無控制臺對象
若為控制臺程序則
Write(count Text);
WriteLn(count Text);
Read(var Text);
ReadLn(var Text);
Escape sequences
\n, \r
\t
\\
\"
Convert.ToChar(65) // Returns ‘A‘ - equivalent to Chr(num) in VB
// or
(char) 65
Console.Write("What‘s your name? ");
string name = Console.ReadLine();
Console.Write("How old are you? ");
int age = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("{0} is {1} years old.", name, age);
// or
Console.WriteLine(name + " is " + age + " years old.");
int c = Console.Read(); // Read single char
Console.WriteLine(c); // Prints 65 if user enters "A"
File I/O
//uses System
Var fwriter: TextFile;
AssignFile (fwriter,’c:\myfile.txt’);
fwriter.WriteLn(‘Out to file.’);
CloseFile(fwriter);
var reader:TextFile; line:String;
AssignFile(reader ,‘c:\myfile.txt’);
Readln(reader ,line);
While Not (line=’’) do
begin
WriteLn(‘line=’ + line);
Readln(reader ,line);
End;
CloseFile(reader);
var str:String = ‘Text data’;
var num :Integer = 123;
var binWriter: TfileStream;
binWriter:= TFileStream.Create(‘c:\myfile.dat’, fmCreate or fmOpenWrite);
try
binWriter.Write(str,sizeof(str));
binWriter.Write(num,sizeof(num));
finally
binWriter.Free;
end;
var binReader: TFileStream;
binReader :=TFileStream.Create(‘c:\myfile.dat’, fmOpenRead or mShareDenyRead);
try
binReader.Read(str,sizeof(str));
binReader.Read(num,sizeof(num));
finally
binReader.Free;
end;
using System.IO;
StreamWriter writer = File.CreateText("c:\\myfile.txt");
writer.WriteLine("Out to file.");
writer.Close();
StreamReader reader = File.OpenText("c:\\myfile.txt");
string line = reader.ReadLine();
while (line != null) {
Console.WriteLine(line);
line = reader.ReadLine();
}
reader.Close();
string str = "Text data";
int num = 123;
BinaryWriter binWriter = new BinaryWriter(File.OpenWrite("c:\\myfile.dat"));
binWriter.Write(str);
binWriter.Write(num);
binWriter.Close();
BinaryReader binReader = new BinaryReader(File.OpenRead("c:\\myfile.dat"));
str = binReader.ReadString();
num = binReader.ReadInt32();
binReader.Close();