Friday, November 02, 2007

DN4DP: The Delphi Language Chapter

We have finally come to an end in the long running series of of The Delphi Language Chapter teasers from Jon Shemitz’ .NET 2.0 for Delphi Programmers book.

All the chapter excerpts that I have posted can be seen by clicking on the DN4DP blog label. As a service to our readers, I'm also including a full list of all the post links here.

Classic Delphi and .NET book in the making

Come get a free sample chapter!

.NET 2.0 for Delphi programmers available now

DN4DP#1: Getting classy

DN4DP#2: Protecting your privates

DN4DP#3: Nesting habits

DN4DP#4: Setting new records

DN4DP#5: Redefining the operators

DN4DP#6: Enumerating collections

DN4DP#7: Inlined routines

DN4DP#8: Unicode identifiers

DN4DP#9: Escaping keywords

DN4DP#10: With a little help from your friends

DN4DP#11: The try-finally-Free pattern

DN4DP#12: Record Helpers

DN4DP#13: Overloaded default array properties

DN4DP#14: .NET platform support: Boxing

DN4DP#15: .NET only: Attributes support

DN4DP#16: .NET only: Floating-point semantics

DN4DP#17: .NET only: Multi-unit namespaces

DN4DP#18: .NET only: New array syntax

DN4DP#19: .NET only: Unsafe code

DN4DP#20: .NET only: Multi-cast events

DN4DP#21: .NET only: Undocumented corner

DN4DP#22: .NET only: P/Invoke magic

DN4DP#23: .NET only: Obsolete features

DN4DP#24: .NET vs Win32: Untyped parameters

DN4DP#25: .NET vs Win32: Casting

DN4DP#26: .NET vs Win32: Initialization and finalization

DN4DP#27: .NET vs Win32: Abstract classes

DN4DP#28: .NET vs Win32: Class references

DN4DP#29: .NET vs Win32: Constructors

DN4DP#30: Delphi vs C#

 

Hope you have enjoyed the series - and that you have bought (or will buy) the book! ;) Jon's book is stuffed with good stuff and is generally a much better read than "mine" chapter.


Note that I do not get any royalties from the book and I highly recommend that you get your own copy – for instance at Amazon.

Thursday, November 01, 2007

DN4DP#30: Delphi vs C#

This post continues the series of The Delphi Language Chapter teasers from Jon Shemitz’ .NET 2.0 for Delphi Programmers book.

Last time we looked at .NET and Win32 constructors. This is the final post in this long running series and it covers the main differences between Delphi and C#.

Note that I do not get any royalties from the book and I highly recommend that you get your own copy – for instance at Amazon.

"Delphi vs C#

Very similar, but different in the details

If you are faced with the task for porting code from native Delphi to C#, or to convert C# code snippets to Delphi, or to make in informed decision of what language to use, it is useful to know the unique strengths and features of each language. In this section we quickly iterate over the highlights of each language and include some tips on porting between them.

Note that we compare Delphi for .NET to C# version 1.0, not version 2.0. It wouldn’t be fair to compare a .NET 1.1 product like Delphi for .NET 2006 to C# 2.0 with its support for generics, nullable types and iterators.

Delphi language highlights

Of the features that we have already covered, class helpers, unmanaged exports and virtual library interfaces are unique features that Delphi has. In one sense class helpers are very similar to the extension methods of the upcoming C# 3.0 standard to support the Linq (Language integrated query) technology. The main difference is that class helpers cannot help interfaces (at least not yet) and class helpers are more structured.

The following table lists the most important Delphi language features that C# does not have and what their alternative is when porting code.

Delphi feature Comment C# alternatives
class helpers Platform-leveling compiler magic

Explicit static methods C# 3.0 extension methods

Unmanaged exports a.k.a. reverse P/Invoke Use C++, hacks
Virtual Library Interfaces a.k.a. dynamic P/Invoke Use unmanaged C++, hacks
sets Limited to ordinal types with <= 256 elements

enum flags, BitArray,
int bit-fiddling

class of references Meta classes System.Type
virtual class methods Meta class polymorphism System.Type, reflection
virtual constructors Class factories Activator, reflection
Type-less var and out parameters Poor-man’s generics C# 2.0 Generics, System.Object function
type aliases, typed types Logical vs. actual types Explicit typing
Default parameters Simpler than overloading Overloading
resourcestrings Simplified internationalization Resources and ResourceManager.GetString
Named constructors Simulated using overloading Overloading
message methods Dispatching windows messages WndProc switch
Variants One-type fits all System.Object boxing
Global routines Non-OOP code Static methods of a class
Global variables Non-OOP data Static fields of a class
Named array properties Multiple array properties

Overloaded this indexer
Nested class with this indexer

Local (nested) procedures Implementation hiding, automatic access to outer variables private method, anonymous method (C# 2.0)
variant records (case) Structure overlaying (union)

[StructLayout(LayoutKind.Explicit)],
[FieldOffset()]

Text files, Writeln, etc Easy input/output Console and Stream classes
Supports Win32, Linux Cross-platform capabilities

Use C/C++,
Mono for Linux


One difference that is important to be aware of is that hard-casts and safe-casts have opposite syntax in Delphi and C#. The safe exception-raising cast is (O as TargetType) in Delphi and (TargetType)O in C#. The nil/null-returning cast is TargetType(O) in Delphi and (O as TargetType) in C#.

C# language highlights

The following C# 1.0 features are not directly available in Delphi, but have alternative ways of achieving the same goal.













































C# feature Comment Delphi alternatives
lock Thread synchronization
Monitor.Enter(O); 
try
// ..
finally
Monitor.Exit(O);
end;
fixedGarbage collection object pinning
H := GCHandle.Alloc(..) 
try
P := H.AddrOfPinnedObject;
finally
H.&Free;
end;
using Deterministic releasing of unmanaged resources
O := TMy.Create; 
try
// ..
finally
O.Free;
end;
C# destructor ~ClassNameGarbage collection deallocate notificationoverride Finalize method
stackallocUnsafe code temporary allocationsGCHandle.Alloc dynamic array

checked/
unchecked

Integer arithmetic overflow checking
{$OVERFLOWCHECKS ON/OFF}
{$Q+/-}
readonly fieldRead-only fields initialized in a constructorconst, read-only property, normal field
returnSet function result and return to caller
Result := O; 
Exit;
volatile fieldMay be modified outside current threadExplicit locks, Thread.VolatileRead/Write
internal accessPer-assembly cross-class implementation details

public,
protected with cracker-cast

ternary ? : operatorInline test and return resultif .. then .. else, IfThen routines
switch (string)Multi-case testing of stringsnested if..then..else, TStringList.IndexOf


In Delphi an overridden Destroy destructor maps to an implementation of IDisposable, while in C# you must implement IDisposable explicitly. In C# a ~ClassName destructor maps to an overridden Object.Finalize method, while in Delphi Finalize must be overridden manually. In most cases, application-level code needs to implement IDisposable, but should not override Finalize – that should be left to low-level leaf-classes in the FCL.

"



Copyright © 2004-2007 by Hallvard Vassbotn