Title: Stumbling blocks and Pitfalls in .NET for Delphi Users
Question: What kind of problems will traditional Delphi users (users of Delphi 3-7) encounter while programming .NET and C# ? What do you need to know to move from Delphi to C# ?
Answer:
C# looks like a mixture of C++ and Delphi, and both
were in fact ancestors Microsoft's new powerful
language. Therefore it is easy to move from C++
or traditional Delphi to C#. Of course there are some
stumbling blocks, traps and pitfalls. For C++ they
are described in detail for instance in the MSDN
Magazine article from Jesse Liberty
"C++ - C#: What You Need to Know to Move from C++ to C#
http://msdn.microsoft.com/msdnmag/issues/01/07/ctocsharp/
Points to remember for traditional Delphi users
(users of Delphi 3-7) are:
*** Confusing Paramters - C# is a case-sensitive language
Delphi
x and X are the same variables/parameters
.NET
x and X are different variables/parameters
*** String literals - C# strings can contain escape sequences
String literals in C# are very similar to string
literals in C. They are clearly a heritage of C or C++
and can contain escape sequences to represent various
control characters like \n (Newline, 0x000a) and \t
(Tab 0x0009) and \0 (Null 0x0000). Verbatim string literals
without escape sequences begin with @:
@"\\machine\share\path1\path2\file.ext"
*** Suprising Results - Implicit Type Conversions
Delphi
x,y : integer;
z : real;
z := x/y; //= 0.5 for x=2 and y=4
.Net
int x,y;
float z;
z = x/y; //= 0 for x=2 and y=4
z = (float)x/y //= 0.5
*** Missing Functions - In .NET everything is an object
C# and .NET are strongly object-oriented. Nearly
everything is an object or a class, even strings
or arrays. If you can not find a certain function
or constant you are used to use, chances are high
that the function or constant exists as a method
or property of a particular class. In some cases,
only the name has changed a bit:
c : tCanvas - Graphics g
c.Textout - g.DrawString
c.TextWidth,
c.TextHeight - g.MeasureString
..
If you can not find a certain API function or
procedure like IntersectRect(), try to look
for a method of the corresponding object. In
the case of IntersectRect() for example the
solution is the Rectangle.Intersect method:
IntersectRect() - Rectangle.Intersect()
IntToStr(i) - Convert.ToString(i) or i.ToString()
Abs() - Math.Abs()
GetDir - Directory.GetCurrentDirectory()
CopyFile() - File.Copy()
FileExists() - File.Exists()
ExtractFileName() - Path.GetFileName()
ExtractFilePath() - Path.GetDirectoryName()
ExtractFileExt() - Path.GetExtension()
ChangeFileExt() - Path.ChangeExtension()
ShowMessage() - MessageBox.Show()
DateTimeToStr(Now) - DateTime.Now.ToString()
fmCreate - FileMode.Create
fmOpenWrite - FileAccess.Write
clWhite - Color.White
clBlack - Color.Black
$ee0000 - Color.FromArgb(238,00,00);
ColorTranslator.FromOle(0xEE0000);
VK_Up - Keys.Up
...
Even operations like inheritance are "objects" in form
of operators. The importance of operators (for example
++,--,etc.) is much larger in C# than in Delphi - the
heritage of C++. Class inheritance in Delphi is done
through brackets "DerivedClass = class(BaseClass)".
In C#, you use the ":" operator. Base-class constructors
for instance are called by the ":" operator, too, not
through functions as in Delphi, where you would use
"inherited create()"
public class BaseClass
{
public BaseClass(string s, double d)
{
... // Initialize fields in class
}
}
public class DerivedClass : BaseClass
{
// Call base-class constructor through ":" operator
public DerivedClass(int i, string s, double d) : base(s, d)
{
... // then initialize fields in this class
}
}