Blogging From Delphi to C#

Name:
Location: Struggletown, Planet Earth, Afghanistan

Software developer with a background in multimedia, video, Delphi and C#. Now working with Ruby on Rails and Adobe Flex (the future of Web apps IMHO)

Tuesday, March 14, 2006

New Blog: Just Enough Software Quality

I've begun a new blog to get some ideas out of my head, and to share
some written code. In my last position I did most of the work in setting up the software team with associated tools towards achieving CE and FDA certification.

In this position I've done most of that again, with different tools.
I think I've "done it right" this time, and for free. Also I 've got several
architectural and development environment ideas to share.

Just Enough Software Quality

Sunday, January 15, 2006

Will the Windows high resolution timer ever overflow ?

The windows high resolution timer is a 64 bit value of an unknown frequency. From experience, the frequency is often 500KHz. I need to represent a null value, and I was wondering whether -1 would be safe ie would the count ever actually equal -1 after an overflow ?

If the count starts at zero on boot, and can count to 2^31 and counts at 500Khz, how many years until it overflows ?

From Slickedit's trusty calculator :

2**63= 9223372036854775808
9223372036854775808/500000= 18446744073709.551616
18446744073709.551616/(3600*24*365)= 584942.41735507203247082699137494
584942.41735507203247082699137494

In 584942 years, it will overflow. I think its safe ;^8

Wednesday, November 23, 2005

Similarities and Differences between Delphi and C#

This document is a heavily modified version by
Gary McGhee of the original by Peter van Ooijen available at
http://www.gekko-software.nl/DotNet/Art01.htm

The Delphi-VCL couple shares a lot with the C#-.NET couple which makes a comparison on items possible.

This is not surprising as Anders Hejlsberg was the lead architect of both languages. The common heritage can be seen, for example, in the similar or identical naming of keywords and methods. Anders has been quoted saying "Good ideas don't just go away".


This document does not take into account Delphi’s .Net version.


Both Delphi and C# have :

· Encapsulation

· Inheritance
Both Delphi and C# are limited to single inheritance, a class can have only one base class.

· Polymorphism

· Class (static) methods

· Overloading
In both languages a method can be declared several times as long as every declaration has a different signature.

· Strongly Typed
Both Delphi and C# have strong typing as a design value. Both provide the is and as operators for type checking.

· No Header Files
Delphi has “unit” files, which each have an interface and implementation section, equivalent to .c and .h files (in C terms). In C# there is no such division. Delphi units “use” each other with the uses clause, like the using clause in C#, and namespaces are specified, not files.

· Abstract methods
An abstract method is a declaration of a method without an implementation. The implementation has to be provided by the descendants.

· Interfaces
An interface is like a class with only abstract members and is in both languages an integral part of the language. In both languages a class can implement any number of interfaces, the interface list is part of the class declaration.

· Properties
To the user of the object a property behaves like any other field. In the actual implementation reading or writing the property will be done by an internal method.

· Events
In Delphi only one particular notification handling method can be assigned to the event-handler. In C# event handlers are multicast, they manage a dynamic collection of delegate objects and fire notifications to all the collection's members.

· Single Inheritance
All classes in both languages stem from one single class; TObject in Delphi and System.object in C#.

· Large standard single-rooted class library
Both environments are heavily based on a large standard tree of classes; known as VCL in Delphi and FCL in C#. These provide basic functionality such as lists, queues, streams and serialization, through to GUI design, XML processing, networking and n-Tier database access.

· Custom Components
Both environments allow custom components to be developed in the language itself, inheriting from the default class library and registered with the IDE. These appear indistinguishable from the components supplied with the product.

· 3rd Party Custom Component Market
Over the years an enormous number of commercially available 3rd party components built on the VCL have been marketed. Many of these have alternate .Net versions available. C# also has a younger but growing 3rd party component market.


· Dynamically Linked Libraries of Components
Known as Assemblies in .Net and Packages in Delphi, they are compiled and may be updated or distributed independently of each other or the application.

· Collections
The VCL has several classes which can be used as a base class for a collection. System.collections in .Net provides classes implementing IEnumerator, and items in such a collection can be enumerated with the C# foreach statement.

· Runtime Type Information
A Delphi published property has RTTI, and can be queried on type information at runtime. In C# the type information of any object is available at runtime through the GetType() method of System.object, the base class of all .NET classes. This is named Reflection in .NET.

· Exceptions
Both languages use exceptions to handle errors. Both languages support the finally clause for cleanup code. In both languages exceptions may be thrown at any time by the system (eg. Divide By Zero), not just by application code. In C# finally can be combined with catching an exception, to achieve this in Delphi two try's have to be nested.

· Interfaces
In Delphi 5 TInterfaced object was added to the VCL, a base class which implements the IUnknown interface and is refcounted. Since then TInterfacedObject has served as a base class for many components.
A .NET class can implement any interface, without doing any refcounting. All objects are being watched by the garbage collector (gc), as soon as an object is no longer referenced by anyone the gc will notice and clean up the object. This is the point where a gc really pays off.

· Minimal need for pointers

For security and to reduce runtime errors, pointers are generally not needed, but may be used in both languages.

· Accessibility Modifiers

In both languages the accessibility of members to other code can be modified using private, protected and public. Delphi adds published to indicate that this property should appear in the object inspector at design time, and should be serialized. C# adds internal to limit access to within the same assembly.



Delphi does not have :

· Attributes
Classes and methods can have metadata, properties which are of importance to the runtime environment.

· Operator overloading
As all variables in .NET are objects, performing operations on them boils down to making methods calls. Methods can be overloaded, in .NET this is also possible for many of the basic operators like +, -, <, etc.

· Struct methods
Delphi supports records, which are similar to structs in C, and do not support methods.

· Versioning of Assemblies/Packages

· Code generation for Strongly Typed DataSets and XML Schemas

· Remoting
Automatic generation of proxy classes, serialization, transport and other plumbing code to support distributed systems development.



C# does not have :

· Automatic persistence of designed forms, controls and other objects

Delphi has always provided a visual design environment that automatically stores (or “persists”) forms, controls and other objects to a text data file, unlike C# which generates the equivalent code. C# will have this ability with XAML in the forthcoming “Avalon”.

· Sets

Delphi allows a “set” or collection of binary flags to be declared that indicates whether each value in a range is present or not. Eg for a font, a single variable of type TFontStyle stores independently the presence or absence of Bold, Underline, and Italics styles.

· Default parameters

Similar to C++

· Virtual Static methods, properties or constructors

Sunday, August 21, 2005

I needed to move on.

Borland is once again changing its focus, and there are suggestions that Delphi may not even be part of Borland for much longer (See CodeFez)
Ten years ago Delphi was fundamentally a far better environment than any of its peers. VB seemed like a toy when I had to use it occasionally. I had just given up my love of the Amiga and moved to Windows for a job. It was some comfort to be working above the horrors of Win32, MFC, GDI etc in the pure OO elegance of the VCL and clean simplicity of OO Pascal (as opposed to C). I could still thumb my nose at MS, and their technical incompetence.
It is testament to this, that Microsoft then head-hunted the main brains behind Delphi (Anders) and built a technically very similar environment (.Net). They have also bought many other industry gurus, and so times have changed. They now have the money, the marketing AND the technology.
Its now much harder to be a renegade, and if you're like me - single income household with a mortgage and baby - financial reality overrides technical ideology. I needed to move on.

Convincing Prospective Employers that your Delphi skills are relevent to C# / VB / .Net

So you know Delphi and find yourself in the job queue again. The Delphi job postings are much less than last time you were looking, and some of them are for converting to .Net. How do you go about crosstraining to .Net, and convincing prospective bosses that your skills are transferrable ?

1) One answer lies above; look for jobs involving converting Delphi projects to C# (or Java, if that interests you). They'll value your Delphi skills and pay you to learn another language.
2) Look into certification. There is a whole industry around training towards MCSD and MCAD, both at home with books, or via training courses. In my experience, books are a far more effective and much cheaper way to learn anything substantial.
3) Provide a Delphi to C# comparison with your resume. You
may use mine

4) At least start working towards MCSD, and say that you are in interviews and in your resume. That sounds like you are serious and approaching this crosstraining in a professional manner. Also, I would guess that whether you are 10% or 80% towards finishing would make little difference to many employers.
5) Start a real world project eg. get involved in an open source project, or build an ASP.Net website. I started this with www.seekdotnet.com and was impressed with their SQL Server package features and price, but can't speak for the quality of their service as I haven't launched my site yet. Again, mention this in your resume and in interviews.
A website project (more than a Windows Forms project) is particularly impressive as they can very easily try it out and see that you're capable of creating something real.
6) Read books about resume writing eg. "What Colour is Your Parachute" is the classic. Spend days on your resume. A day spent on it could equal a month worth of waiting for job ads to appear, waiting for them to get back to you etc.
7) Research companies you would like to work for. Microsoft provides a listing of "Partners" on its website, which is a pretty complete list of .Net shops in your area. Get a directory of your local "technology park" or precinct. Look for government innovation development programs, and the list of companies that may provide.
8) Don't just wait for job ads to appear. Print out your resume, dress up, and approach them. My theory here is that when job ads are written, critieria is decided upon based on their ideal employee with phrases such as "12 months .Net experience". Immediately you are behind with your measley 2 weeks of .Net experience. When are face to face with them in their office however, you are a real person and they can judge your character, enthusiasm etc and may even make a position for you that didn't previously exist. They may not have time to go through with the hassle of advertising when really they need you, or they may be just about to advertise. I did this for about 4 days and got one 4 week C# contract followed by a job offer, 1 call encouraging me to apply for a new position and one email asking me if I was still looking for work, 4 weeks later. This was after 3 months of answering job ads with little response. By the way, my new job still came from answering an ad.
9) Keep all job ads that interest you, even ads for the wrong job but the right sort of company. They may be worth approaching later, and may contain important info such as the name of a manager to call. Having someone to ask for is an easy way to get past a difficult receptionist. Also, if you were the second best candidate this time, you might get the job next time. Resist the urge to resent that they didn't choose you.
10) Companies using Delphi, past and present are still your friend. They will be easy to convince that your Delphi skills are valuable, even if they no longer use it. My 4 week C# contract was with a previosly Delphi based company, and my current boss has done some serious Turbo Pascal work in the past.

Good luck !

Saturday, August 20, 2005

C# Limitation 1: no Virtual Static Methods

After some months of intensive C# learning and development, I've run into few limitations - things that Anders and others must have intentionally chosen not to do. For example, "Virtual Static Methods" - sounds all academic right ? How about this :
I am writing an object messaging library, and I want to have the objects themselves recognise their own binary stream, so that when deserializing an object from binary, I can run through a list of registered message classes, call a virtual function, and if it returns true, that is the correct class to use, and so I would call its Constructor to create an instance, and then read in its properties.
C# has two barriers to this that Delphi handles fine.
1) In C#, static functions cannot be virtual. In Delphi you would declare the message base class with a static virtual method
Recognise(TStream aStream): boolean
then override it with each specific type of message. In C# a method can be static or virtual, but not both. To use a virtual instance (non-static) method I must have already created the object, but I want to use the Recognise method to determine whether to instantiate that class in the first place ! You could I suppose implement the "prototype" design pattern, where you keep a list of objects (rather than classes) available for cloning.
2) In C#, constructors cannot be virtual either, so when I know what class to create, I can't just create it polymorphically.

Thankfully C# does have a very powerful equivalent to Delphi's RTTI (Run Time Type Information) known as Reflection and we can solve these problems with it.I solved the first issue with a static property called MessageID that must be declared in every message class (non-virtually). The message creating code keeps a list of registered classes (more on this later), reads a certain byte from the incoming stream and looks for a match with the values of MessageID in the list. It now has the class required and must create it (issue 2).
To do this, it again uses reflection in a method (see CreateFromClass() below) that will create an instance of any class having a constructor with no parameters.
AliasClassFactory contains the code for registering and creating the classes. Message classes can be specifically registered with their ID as a string (the string can of course be a number).
To get the MessageID property value from any class use this utility method :

public static object GetStaticProperty(Type aType, string aProperty) {
return aType.InvokeMember(aProperty, BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy, null, null, null);
}

Whenever a method has a parameter of type Type like aType above (did you get that?), you can call it like this with a class :
int id = (int) GetStaticProperty(typeof(MyMessage), "MessageID")
or like this with an instance of a class
int id = (int) GetStaticProperty(myMessage.GetType(), "MessageID")


using System;
using System.Reflection;
using System.Collections;
using System.Diagnostics;

namespace myspace {

/// Register classes with aliases, then create them from the alias.
public class AliasClassFactory {
ArrayList list;
Type baseClass;

/// helper class used for each item in the list of classes
protected internal class AliasClassItem {
Type vClass;
string vAlias;

public Type Class {
get {
return vClass;
}
}
public string Alias {
get {
return vAlias;
}
}

public AliasClassItem(Type aClass, string aAlias) : base() {
this.vClass = aClass;
this.vAlias = aAlias;
}
}

///Create factory. Registered classes must descend from base class given here
///(can be object)
public AliasClassFactory(Type aBaseClass) : base () {
baseClass = aBaseClass;
list = new ArrayList();
}

///Classes must be registered with an alias before being created by the factory
public void Register(Type aClass, string aAlias) {
if (!aClass.IsSubclassOf(baseClass))
throw new Exception("Class must be a subclass of "+baseClass.FullName);

Type vClass = ClassFromAlias(aAlias);
if (vClass != null)
throw new Exception("Alias already registed with class "+vClass.FullName);

list.Add(new AliasClassItem(aClass,aAlias));
Trace.WriteLine("Class "+aClass.FullName+" was registered with alias :"+aAlias);
}

///Method for creating an object from a class. Requires constructor with no arguments.
///This limitation could be removed later.
public static object CreateFromClass(Type aClass) {
ConstructorInfo constructorInfo = aClass.GetConstructor(
BindingFlags.Instance | BindingFlags.Public,
null,
CallingConventions.HasThis,
new Type[0] {},//aPars,
null
);
if(constructorInfo != null)
return constructorInfo.Invoke(null);
else
throw new Exception("Constructor not found");
}

///Returns the class given an alias
public Type ClassFromAlias(string aAlias) {
foreach (object obj in list) {
if ( String.Compare( ((AliasClassItem) obj).Alias, aAlias, true)==0 ) {
return ((AliasClassItem) obj).Class;
}
}
return null;
}

///Creates a class given an alias.
public object CreateFromAlias(string aAlias) {
Type vClass = ClassFromAlias(aAlias);
if (vClass==null)
throw new Exception("Class not registered");
return CreateFromClass(vClass);
}
}
}

Thursday, June 30, 2005

I'm employed !

Long time between posts. I'm employed ! I'm working for DTI doing security and signage for buses and trains. Lots of C#, which is great. The boss is a long-time Turbo Pascal developer, so perhaps thats why he accepted my "C + Delphi = C#" argument. I've made the transition ! I'll post a document I wrote (based on another) comparing the two languages for prospective jobs.

Tuesday, March 01, 2005

First Microsoft developer conference-thing

Microsoft held a "Security Summit" in Perth today. The developer track had little to do with security, but that suited me. It was all about Visual Studio 2005, (including Team System, the new all-encompassing team version). Impressive and highly practical for companies. I bet its expensive. For many companies, why would you get anything else ? I mean, I like to think that the software industry can be like a gentleman's war, competing fairly, but when MS owns most of the soldiers (and many of the best), how can this happen ? And less vendors is certainly more convenient and encourages interoperability - though certainly not desirable in an ethical big-picture sort of way, of course.
I borrowed the MCSD book set from a friend too, so I'm set to learn C#.