.NET and Delphi handle enumerations quite differently. Because of this CrossTalk has to do a bit of a translation and cannot translate .NET enums directly into Delphi enums.
Except in later Delphi versions with scoped enums, Delphi enums have no namespace.This is why Delphi enums typically have a prefix. i.e. clRed, clBack, etc.
Let's take the example of System.Xml.ConformanceLevel which is an enum that look like this:
public enum ConformanceLevel { Auto, Fragment, Document }
If CrossTalk translated it as:
type ConformanceLevel = (Auto, Fragment, Document);
Then Auto, Fragment, and Document become global identifiers and would easilyconflict with other identifiers. CrossTalk could have prefixed each like this:
type ConformanceLevel = (ConformanceLevel_Auto, ConformanceLevel_Fragment, ConformanceLevel_Document);
This gets a bit ugly, but potentially in many cases could create conflicts as well. Because of these factors CrossTalk instead creates a class with class functions.
type ConformanceLevel = class public class function Auto: Longword; class function Fragment: Longword; class function Document: Longword; end; implementation { System.Xml.ConformanceLevel } class function ConformanceLevel.Auto: Longword; begin Result := 0; end; class function ConformanceLevel.Fragment: Longword; begin Result := 1; end; class function ConformanceLevel.Document: Longword; begin Result := 2; end;
We considered using read only properties as this would be more efficient to read values, however this has the drawback of requiring the class to be created first, and also then later destroyed. Later editions supported class properties, but originally we supported Delphi 7 which did not support this language feature.
CrossTalk translates enum references to LongWord.
property ConformanceLevel: Longword {Enum: 'System.Xml.ConformanceLevel} read ConformanceLevelRead write ConformanceLevelWrite;
While this removes type safety of enums, it allows natural code to be written.
xSettings := XmlReaderSettings.Create; try xSettings.ConformanceLevel := ConformanceLevel.Fragment; xSettings.IgnoreWhitespace := true; xSettings.IgnoreComments := true; ........ finally xSettings.Free; end;
We considered emitting one enum per unit and using unit qualifications. The problem is that to do this the unit still has to be added to the uses clause, thus entering it into that units global namespace. This does not really enable namespaces, so much as it forces disambiguation. Not only would the reference to the enum need to be qualified, but so would the opposite conflicting symbol(s). With a lot of conflicts (as would exist most definitely) it creates quite a mess.
When we originaly built CrossTalk, we supported Delphi 7 which did not support this newer Delphi language feature.