C # for delphi development

xiaoxiao2021-03-06  73

C # for delphi wevelOpers1.0 022202

Foreword

This document is intended to be a reference for those Delphi programmers who want to learn C #. It explains how to translate your existing knowledge to C #. I hope you could forgive my mistakes, I'm not an english speaker and you are invited to send ME Any Bugs or Incorrect Information You Find At Studio@qadram.com, I will fix it as soon as possible.

Introduction

C # IS a Component-Oriented Language, In The Same Way Delphi and C Builder Are, But It Goes a bit beyond this concept. This is not a c # manual, after the means manual, you must buy some c # book to Learn All The New Features C # Have and Delphi Not. Some Descriptions and Difference Are Explained "Roughly", IS Just An Introduction To C # for delphi development, it's not an in-depth C # manual.

Some Things this Manual Doesn't Cover

How to compile or execute C # programs Attributes Interfaces Nested Classes Versioning C # language syntax Conversions Arrays Indexers Enumerators User-defined Conversions Operator Overloading COM .NET Framework XML

Is this Manual for you?

If you are a Delphi developer who wants to know how to translate your knowledge to C #, this is the first document you might want to read. It introduces you in the C # by explaining how to do the things you already do with Delphi. This manual Is Only About The Language C #, NOT The .NET Platform Nor The Visual Studio .NET IDE, NOR Components.

About the Author

José León Currently Works As Web Developer for a Company In Spain, IF You Want To Know More About Him, Just Go To http://www.qadram.com

QuickStart

Look at this Source Code:

Using system;

Class Hello

{

Public static void main (string [] args)

{

Console.writeline ("Hello, From C #"); for (int Arg = 0; arg

{

Console.WriteLine ("arg {0}: {1}", arg, args [arg]);

}

}

}

When the Program Loads, The Main Function IS

Executed, IT Writes A String to the console and

Iterates through the parameters to dump the

Number of Parameters and ITS Value.

Main Differences:

Using INSTEAD OF USES

To Add External FunctionAllity

There's no code outside a class,

There Are no global functions in c #

The IMplementation of a Method IS

Tied to ITS Declaration

DataTypes

The Following Table Shows The Correlation

Between Delphi Data Types and C # data

Types:

Delphic # bytebeteshortintsbytesmallintshortwordushortintegerintShortWordushortintegerintShibardinal, LongwordUintint64longulongsinglefloatDoubledoublecurrencyDecimalstringstringCharCharBooleanBool

The Main Diference Between Delphi

DataTypes and C # DataTypes IS Not ITS Name, in

C #, Datatypes Are Derived from the base class

Object, So it's Possible to WRITE

Sentences like this:

Console.writeline ("Value IS: {0}", 3.Tostring ());

Which is not Possible in Delphi, this

Technique Is Called Boxing.

Exception Handling

I can't See Many Differences Between C #

Exception Handling and Delphi's One, IT'S

Another Syntax But Nothing Moreing Moreing More:

Try .. except .. End

Try

{

INT J = 22 / ZERO;

}

Catch (Exception E)

{

Console.writeline ("exception" E.MESSAGE);

}

If you want to catch diffreent Kind of

Exceptions You Just Only Need to Write Several

Catch Blocks. The Ancestor Of All

Exceptions is the Exception Class, The EXCEPTION

Same as delphi.

Try

{

INT J = 22 / ZERO;

}

Catch (DivideByzeroExcection E)

{

Console.writeline ("exception" E.MESSAGE);

}

Catch (Exception E)

{

Console.writeline ("exception" E.MESSAGE);

}

The catch block what catches the cardyzeroexception is the more specific

Match.

Try..finally..nd

C # also supports try..finally

Using Similar Syntax To Delphi

FILESTREAM F = New FileStream ("DATA.TXT", FileMode.Open;

Try

{

// Perform Operations with the file

}

Finally

{

f.close ();

}

There's Another Option Which is equivalent to

This delphi code:

Try

Try

Except

// manage here your exceptions

end

Finally

// Perform Some Cleanup Here

END;

IN C # you can write:

Try

{

}

Catch (Exception E)

{

Console.writeline ("exception" E.MESSAGE);

}

Finally

{

// Perform Some Cleanup Here

}

In Delphi, You Should Destroy Any Object

You create or free any resource you allocate.

The primary use of exception handling is to

EnSure Everything is destroyed and freed.

Because C # HAS Garbage Collection, you don't

NEED TO WORRY About this, you will use

Exception Handling Only To Ensure The Proper

Finalization of Operations, SO this Improves

The efficiency of the code.

Classes

C # classes work like delphi, you don't

Need to Learn New Oo Concepts, The Main

Difference, At Source Code Level, Is The Code

Is Written Just Below The Prototype of A

Function.

Class myclass

{

Public int myfunction ()

{

Return (5);

}

}

Also You Must Specify THE VISIBILITY OF

Each Member of a Class (Field, Method, ETC),

Because They isy default. for

EXAMPLE:

Class Myinteger

{

INT INTEGER = 0;

}

If you create an instance of

Myinteger and you use the integer field

Of the myinteger class, this will

Product an error Because IS

Private:

Class testprivate

{

Public static void main ()

{

Myinteger mi = new myinteger ();

Console.writeLine ("{0}", mi.integer;

}

}

This Will Produce An Error, You Mustspecify Public When Decilaning a Member

Visible to other classes.

In the previous case, you don't need

Destroy the Mi Variable, The Garbage

Collector Does It for you. in Delphi you can

Use self inside a class to reason to the

Current Instance, In C # use this instead

Self.

Constructors

Constructors are not labeled with the

Constructor Reserved Word, In C #, Constructors

Are Me MEMBER FUNCTIONS with The Same Name of The

Class:

Class Point

{

Public Point (int x, int y)

{

THIS.X = X;

THIS.Y = Y;

}

Public int x;

Public int y;

}

Ref and out parameters

To Get Several Values ​​at ONCE FROM A

Function, in Delphi you use var, to

INDICATE A Reference Parameter, The Function

Can Modify The Parameter and The Caller Will

Know the New value.

There area Two Ways to do this in c #, you

CAN use ref or out. the

Difference is The Compiler Won't allow to pass

Uninitialized Variables as REF

Parameters.

Class Point

{

Public Point (int x, int y)

{

THIS.X = X;

THIS.Y = Y;

}

Public void getPoint (Ref Int X, Ref Int Y)

{

x = this.x;

Y = this.y;

}

INT X;

Int Y;

}

To call the getpoint member of the point

Class, You Should Call IT AS:

INT x = 0;

INT Y = 0;

Apoint.getPoint (Ref x, ref y);

IF you forget to initialize the

Parameters, The Compiler Will Generate An

Error, IF you don't want this, just change

Ref by out.

OVERLOADING

To Declare Several Methods in a class

With The Same Name and Different Parameter

List, you don't need to mark the as

Overload. The Compiler Chooses Which To

Call by matching the parameters in the call trum

The parameters declared for the

Function.

Inheritance

To create Derived Classes from Base

Classes, you can do it this way:

Class Baseclass

{

Public BaseClass ()

{

// do something

}

}

Class DerivedClass: Baseclass

{

Public derivedclass ()

{

}

}

One Big Difference IS Constructors Cannot

Be inherited, so you must ask, how can I call

The base class constructor ?. in Delphi, you can

Use the inherited reserved word, in c #

You Use the base syntax. Look at The Base SYNTAX.

FOLLOWING SAMPLE:

Class Baseclass

{

Public BaseClass (String Param, Int Value)

{

This.Param = param;

THIS.VALUE = VALUE;

}

String param;

Int value;

}

Class DerivedClass: Baseclass

{

Public DerivedClass (String Param, Int Value): Base (param, value)

{

}

}

Using the base syntax, you call

The constructor from the base class with the bas

Parameters of the constructor of the derived

Class, if You Omit The Base Syntax, The Base Syntax, The Base

Base Class Constructor Will Be Called With No

Parameters.

Virtual functions

To Declare Virtual Functions and Override

THEM IN DERIVED CLASSES, THE SYNTAX IS VERY

Similar to delphi, To ALLOW A FUNCTION BE

Overritten in a Derived Class, You Must Declare

IT As Virtual, And in a Derived Class To

Override a Function from the base class, you

Must Declare it as override.

Class Baseclass

{

Public BaseClass (String Param, Int Value)

{

This.Param = param;

THIS.VALUE = VALUE;

}

Virtual public getValue ()

{

Return (Value);

}

String param;

Int value;

}

Class DerivedClass: Baseclass

{

Public DerivedClass (String Param, Int Value): Base (param, value)

{

}

OVERRIDE PUBLIC GETVALUE ()

{

Return (Value * 5);

}

}

Abstract Classes

If you want to force a derived class to

Override One or more Members, You Can Declare

THEM As Abstract, this means you don't

NEED TO CREATE AN IMPLEMENTATION for Thatmember in the base class and you are forcing a

Derived Class to Implement IT.

There Are Several Differences Between C #

And Delphi, in Delphi, you can declare an

Abstract MEMBER, But you are not forced

To Implement It On a Derived Class, You Will

Get Just A Warning, And in Runtime, IF you call

This Member, You Will Get An Abstract

Error.

IN C # you are forced to import AN

Abstract MEMBER IN A Derived Class, IF

You don't do it, The program won't compile.

Also, if you declare an abstract member

ON a class, you must declare the class as

Abstract and you can't create installation

Of That Class Because IT Contains Missing

FunctionAlity. Look at this Example:

Abstract Class Baseclass

{

Public BaseClass (String Param, Int Value)

{

This.Param = param;

THIS.VALUE = VALUE;

}

Abstract public getValue ();

String param;

Int value;

}

Class DerivedClass: Baseclass

{

Public DerivedClass (String Param, Int Value): Base (param, value)

{

}

OVERRIDE PUBLIC GETVALUE ()

{

Return (Value * 5);

}

}

You cannot Create Instances of Baseclass,

And if you don't override the member getValue,

The Program Won't compile.

Sealed Classes

There's Another Feature I Think Delphi

Doesn't Have, IS Called Sealed Classes, and IS

A Way to Prevent DeriVation from a base

Class.

This Program Will ProductAN

Error:

Sealed Class Myclass

{

Myclass ()

{

}

}

Class Derived: Myclass

{

}

Class Member Accesibility

In Delphi, You Can Declare Several

Classes in The Same Unit, Let's Suppose Class A

And Class B, if you declare a private member on

Class A, You CAN Access That Member INSIDE

Class B.

Tclassa = Class

Private

A: Integer;

END;

Tclassb = Classpublic

Procedure hello;

END;

IMPLEMENTATION

Procedure tclassb.hello;

VAR

Classa: tclassa;

Begin

Classa: = tclassa.create;

Classa.a: = 5;

END;

In C # this is not the default behaviour,

To Achieve this Behaviour, You Must Declare T

MEMBER AS INTERNAL.

Public Class Classa

{

INTERNAL INT A;

}

Public Class Classb

{

Public void Hello ()

{

Classa ca = new classa ();

Ca.a = 5;

}

}

In c # there is a concept called

Assembly, Which Can Be Considered Asia

Package for delphi development. Declaring

INTERNAL A MEMBER OF A Class, You CAN

Access That Member from any class inside the

Same assembly, but not from a class outside the

Assembly.

The Internal Syntax Can Also Be

Used with classes, Because if you don't specify

a Visibility for a class (i.e. public), The

Class Could NOTBE. Outside The assembly.

TO CREATE A Class That Could Be Used "Only"

INSIDE The assembly, Declare IT AS

Internal.

Destuction

There Are Important Differences Between

Delphi's Memory Management and C # 's One. In

Delphi you sell take care to destroy Each and

Every Object You Create To Avoid Memory Leaks,

But in c # you don't have to worry about

That.

Strictly speaking, c # doesn't has

Destructors, At Least Not in The Way Delphi

Does. in c # a destructor is like a finalizer

And is caled by the garbage collector when the garbage

Object is collected. so the destructor is not

SO USeful As in Delphi, We Must Provide Another

Method for the user of out j ject to perform

Cleanup.

Static Fields and Member Functions

In Delphi, THE Easiest Way (and the only

Way I know) to have a field shared by several

Instances of the Same Class, IS Declare IT

Outside the class. declare it as a globalvariable or a local variable under the

Implementation section. But C # Gives US Another

Way to do it, you can Declare a member of a

Class as static, this means, it's value

Will Be Shared Among All The Instances of The INSTANCES OF

Same Class, And It's Accessed THROUGH THE NAME

Of the class, instead the name of the

INSTANCE.

Class StaticClass

{

Public staticclass ()

{

INSTANCES ;

}

PUBLIC Static Int Instances = 0;

}

Class Statictest

{

Public static void main ()

{

StaticClass sc = new staticclass ();

Console.writeline (staticclass.instances);

StaticClass sc2 = new staticclass ();

Console.writeline (staticclass.instances);

}

}

Also, You Can Declare Methods of The

Class as static, and in That Case, Works

In The Same Way AS Class Methods in

Delphi.

Constants

To Declare a constant, you just need

Declare it with the const modifier and

Assign IT a Value, But you must include the

TYPE OF THE VALUE.

Public const Int value = 33;

But there is another powerful feature to

Allow US Initialize Constants to a Value WE

Don't Know At Compile Time. this Feature IS

Called readonly. if we use

Readonly modifier instead the

Const modifier when declaring a

Constant, We are allowed to set its value. ONLY

At the constructor of a class. if we try to ration. IF WE TRY TO

Modify it in another location, we will get an

Error.

Class ReadonlyClass

{

Public ReadonlyClass (Int Value)

{

THIS.VALUE = VALUE;

}

Public Readonly Int Value;

}

In this Way, Value Could Not Be

Modified in Any Part of The Program Except in

ITS Constructor. Works Very Similar To Readonly

Properties, But in My Opinion, THE SYNTAX IS

Much more clear.

Variable parameters

In Delphi, A Function Can Take a Variablenumber of Parameters, C # is Able To Do this in

A fancier warbause in c # Everything is an

Object, Take a Look At this code:

Class VariableParameters

{

Public void write (string line, params object [] args)

{

For (int index = 0; index

{

Console.writeline (args [index] .tostring ());

}

}

}

Class testvariableparameters

{

Public static void main ()

{

VariableParameters vp = new variableparameters ();

Vp.write ("Hello", "World!");

vp.write ("params:", "a", "b", 12, 15);

Object [] arr = new object [4];

Arr [0] = "these";

Arr [1] = "all";

Arr [2] = 4;

Arr [3] = "Params";

vp.write ("params:", arr);

}

}

IF we use the params keyword on a

Parameter of a function, we are able to pass as

Many Parameters as we want to That function.

The Compiler INTERLY Converts That List of

Parameters to an Array and Calls the function

With That Array, The Same as in The Third

Call.

Structs

STRUCTS Are Really Different To Dephi

Records, Because They Inherit from Object, ACT

Like Objects But With A Few Restrictions, They

Can't inherit from any other type and other

Classes can't inherit from them. It's really

Strange to See a struct that has methods, but

WE Must Think That Is An Object, in The Same

Way an integer or a string.

SO We can write this code:

Struct Rect

{

Public RECT (INT X1, INT Y1, INT X2, INT Y2)

{

THIS.X1 = x1;

THIS.Y1 = Y1;

THIS.X2 = x2;

THIS.Y2 = Y2;

}

Public override string toString ()

{

Return (String.Format) - ({0}, {1}) - ({2}, {3}) ", X1, Y1, X2, Y2);

}

Public INT X1;

Public int y1;

Public int x2;

Public int y2;

}

Class TestRect

{

Public static void main ()

{

Rect Bounds = New RECT (100, 100, 200, 200); Console.WriteLine ("Bounds: {0}", Bounds;

}

}

This Code Is So Strange to a Delphi

Developer, Because First, DECLARES METHODS IN A

Struct, Second, A Method Uses the override

Reserved Word, And Third, The Struct Is Written

To the console.

WE CAN DECLARE METHODS IN A STRUCT

Because is an Object, Because is an Object WE

Can Override Certain Functions of the Object

Ancestor (Tostring Is Available for All

Objects, and the toString method is called for

Each An Every Object Is Passed to The WriteLine

Function.

Sentences

I'm not going to write here all the

Sentences of delphi and its Equivalent in C #

BECAUSE MOST Part Are the Same In C , you

SHOULD Read Another Tutorials / Books About

That.

Switch

Switch is equivalent to copy in Delphi,

But Has A Total DiffERENT SYNTAX:

Switch (condition)

{

Case 1:

Case 2:

// Do Something Here for Case 1 and case 2

Break;

Case 3:

// Do Something Here for Case 3

Break;

DEFAULT:

// Handle Here The Default Case

}

Works Very Similar To C But It Requires

A Break at the end of each case block, this is

A Common Mistake In C , So The Compiler Gives

An Error if there's no Break.

Foreach

C # incorporates a feature to make

Items Simpler, IS Called Foreach, And

Allows to Itereate Easily Through AN Array (Also

Allows Another Types, But It's Outside of the

Scope of this manual).

LOOK this Code:

Public Static void foreachtest (arraylist myarray)

{

For (int i = 0; i

{

MyObject Current = (MyObject) MyArray [i];

Console.WriteLine ("item: {0}", current);

}

}

With foreach, you can write the prep

As Follows:

Public static void foreachtest (arraylist myarray) {

Foreach (MyObject Current in MyArray)

{

Console.WriteLine ("item: {0}", current);

}

}

Return

Return, Returns to the Calling Function

And Optionally Returns a Value, IS LIKE ASSIGN

A Value to Result and make an exit.

AS and IS

Thase Operators Can Be Used in the Same

Way in Delphi, You Can Know The Type of An

Object / Interface and Force It to be of A

Specified Type.

Strings

Because strings are Objects Too, you can

Apply to string Variables Several Methods to SEVERAL METHODS TO

Compare Them, Make Operations, Iterate,

ETC.

This is a brief List of all the methods

That Supports a string:

Compare () Compareordinal () compareto () endswith () StartSwith () indexof () LastIndexof () CONPYTO () INSERT () JOIN () PADLEFT () Padright () remove () rff () Padright () remove () Replace () split () subside () Replace () split () Substrng () TOLOWER () TouPper () Trim () Trimend () Trimstart ()

To make String Processing Easier, There's

a class caled stringbuilder which can be

Useful to make such operations.

Regular Expressions

To Deal with regular expressions, there.

a class called regex which handles all this

Stuff. You Just Create a New Object of Regex

Class and as parameter you use the regular

Expresion, Then You Can Use the Several Methods

Provided with this class to perform operations

TO STRINGS.

PROPERTIES

The Syntax for Properties Is Totally

Different to del Phi's One. in Fact, IF you

Don't pay attention, you can't see a

Property, Because IT Looks Like A

Method.

The Concept Is The Same, A Property IS A

Way to get the value from a field of an object,

Or to set That Value, A Property Itself it's

NOT A Value. Look That Code:

Class test

{

PRIVATE STRING NAME;

Public String Name

{

get

{

Return Name;

}

set

{

Name = value;

}

}

Personally, i prefer the way delphi

Declares Properties, for Example, you see the

Value Parameter of the Set Accessor, But

Here Is Hidden. IF a property HAS Only A Get

Accessor (Getter), IT's A

Read-Only Property, And iF IT HAS Only A Set

Accessor (SETTER) IT'S A

Write-only property.

Delegates

In Delphi You CAN WRITE:

Type

Twakeupevent = Procedure (Sender: TOBJECT; WHEN: integer) OF Object;

You are Creating a Procedural Type, THEN

You can Declare Variables of That Type, And

This Mechanism Is Needed When Decilang

Events.

IN C #, The Concept is Called Delegate, in

C #, The Previous Line Can Be Written As

Follows:

Public Delegate Void Twakeupevent (Object Sender, Int when);

Because in C #, All The Code Must Be

Written Inside a class, you don't need

Specify of Object. after this decaration you

Can Write:

Class Wakeme

{

Public Delegate Void Twakeupevent (Object Sender, Int when);

Public void Wakemeup (Twakeupevent Wakemeup)

{

WakeMeup (Anobject, 500);

}

}

But this Has Some Drawbacks, Because you

Must Create An Instance of The Delegate,

Passing as an argument, the function you want

To be caled.

Class test

{

Public Static Void Notified (Object Sender, INT WHEN)

{

Console.writeline ("When: {0}", when);

}

Public static void main ()

{

Wakeme WM = New Wakeme ();

Wakeme.twakeupevent ev = new wakeme.twakeupevent (notified);

Wakeme.wakemeup (EV);

}

}

Events

Events in c # area based in delegates, and

There's a design conveterion to design THE

Delegates to take always two parameters, the

First Is The Object That Fired The Event and

The Second Parameter Is An Object That Contains

The Information About The Event, this Object IS

Always Derived from Eventargs. Indelphi, The Convenction Is To Define An Event

With sender as first parameter and the

REST OF INFORMATION IN SEPARATE Parameters.

Class MyEventArgs: Eventargs

{

Public myEventArgs (String Name, String Value)

{

THIS.NAME = Name;

THIS.VALUE = VALUE;

}

Public String Name

{

get

{

Return (Name);

}

}

Public String Value

{

get

{

Return (Value);

}

}

String name;

String value;

}

Class MyNotify

{

Public Delegate Void MyEventHandler (Object Sender, MyEventArgs E);

Public Event MyEventhandler OnMyeventHandler;

Protected Void Onmyevent (MyEventargs E)

{

IF (OnMyeventHandler! = NULL) OnMyeventHandler (this, e);

}

Public void NotifyEvent (String Name, String Value)

{

MyEventargs E = New MyEventArgs (Name, Value);

OnMyEvent (E);

}

}

Class mywatcher

{

Public myWatcher (MyNotify MyNotify)

{

THIS.MYNOTIFY = MyNotify;

MyNotify.onMyevent = new mynotify.myeventhandler (myFunction);

}

Void MyFunction (Object Sender, MyEventArgs E)

{

Console.writeline ("new mail: {0}

{1} ", E.NAME, E.VALUE

}

MYNOTIFY MYNOTIFY;

}

Class test

{

Public static void main ()

{

MyNotify MyNotify = new mynotify ();

MyWatcher MyWatcher = new mywatcher (mynotify);

MyNotify.NotifyEvent ("this is a name", "this is a value");

}

}

The First Time I Saw this Code, I Started

To Think That C # is Not as Good with Events AS

Delphi, But Let's Look at the line:

MyNotify.onMyevent = new mynotify.myeventhandler (myFunction);

THIS LINE Assigns a Handler To The Event,

But then, why =, INSTEAD A Simple Assignment?

In C #, INSTEAD Assign a Pointer to an Event,

You are "subscribing" to a notification list,

That Means, Several Functions Can Be Notified

When An Event Is Fired without do anythingspecial. this feature is really useful. in C #,

This Feature IS Called

Multicast, And there is TWO

Things you must be aware, The Order in Which

Delegates Are Called is not defined, and if one

Delegate throws an exception, Maybe, The Other

Delegates Are Not Called.

Conclusion

IF you get a c developer who change to

Delphi Due Rad Capabilities (this is my story

;-)), you will feel Very Comfortable with C #,

IT GIVES you the best of c with a delphi

Flavour.

转载请注明原文地址:https://www.9cbs.com/read-119967.html

New Post(0)