Konečně jsem se dostal k tomu abych si vyzkoušel Delphi Prism a tak se podělím o pár dojmů. Ale pořád platí, že primárně se zde budu zabývat nativním Delphi (tj. klasickým).
Delphi Prism, je sice kompilátor dialektu Object Pascalu do .NET, ale není původním produktem firmy Embarcadero (i když na něm v současnosti spolupracují), ale firmy RemObjects.com, která ho původně vyvinula pod názvem Oxygene. To je také jeden z důvodů, proč Delphi Prism používá MS Visual Studio Shell, tj. IDE Visual Studia bez konkrétního jazyka. Pokud ale máte již nainstalováno VS (pro Delphi Prism 2010 je podporováno VS 2005 a VS 2008, pro Delphi Prism 2011 i VS 2010) je Delphi Prism nainstalováno do něj.
V tomto textu budu popisovat Delphi Prism 2010. Delphi Prism 2011 podporuje navíc VS 2010, .NET framework 4, vylepšenou podporu pro paralelní programování, Copy a Paste C# kódu jako Delphi Prism Code, obsahuje podporu pro MonoTouch (tzn. pokud ho máte můžete vyvíjet pro iPhone) a další efektové.
Instalace Delphi Prism
Instalační balíček má 300M, pro Delphi Prism 2011 cca 1.7G (obsahuje i C# Develop).
První důležitou věcí je záložka Project Options - Compatibility.
Kompatibilita
Pokud nezaškrtnete na uvedené záložce kompatibilita příslušné škrtadla, připravte se, že ze stávajícího kódu moc nepřeložíte.
Jen jedna poznámka: Delphi Prism opustil konvenci u typů začínat T, např. TForm1.
Příkladem nové syntaxe může být vytváření objektu:
var
frm:Form1;
begin
frm := new Form1(); // místo Create použijeme new jako v C#
//frm := Form1.Create(); // jen se zapnutou kompatibilitou
frm.ShowDialog;
end;
Druhou zásadní věcí je nahrazení procedure a function klíčovým slovem method pro oboje. Pokud zapnete kompatibilitu tak klidně můžete používat původní procedure a function. Osobně nevím, zda to byl dobrý krok: sice mne x-krát štvalo, že musím přepsat procedure na function, na druhou stranu to je pro mne přehlednější.
method frmMain.Dispose(disposing: Boolean);
begin
if disposing then begin
if assigned(components) then
components.Dispose();
//
// TODO: Add custom disposition code here
//
end;
inherited Dispose(disposing);
end;
Formulář
Jak vypadá třída formuláře?
namespace WindowsApplication1;
interface
uses
System.Drawing,
System.Collections,
System.Collections.Generic,
System.Linq,
System.Windows.Forms,
System.ComponentModel;
type
/// <summary>
/// Summary description for MainForm.
/// </summary>
frmMain = partial class(System.Windows.Forms.Form)
private
procedure button1_Click(sender: System.Object; e: System.EventArgs);
method checkBox1_CheckedChanged(sender: System.Object; e: System.EventArgs);
protected
method Dispose(disposing: Boolean); override;
public
constructor;
end;
implementation
….
Zapomeňte na DFM soubory, celý popis formuláře je stejně jako v C# a VB.NET v kódu. Díky deklaraci partial class je kód formuláře (např. pro Main.pas) ve Main.Designer.pas (soubor je automaticky upravován IDE):
interface
uses
System.Windows.Forms,
System.Drawing;
type
frmMain = partial class
{$REGION Windows Form Designer generated fields}
private
components: System.ComponentModel.Container := nil;
button1: System.Windows.Forms.Button;
checkBox1: System.Windows.Forms.CheckBox;
menuStrip1: System.Windows.Forms.MenuStrip;
FileToolStripMenuItem: System.Windows.Forms.ToolStripMenuItem;
ExitToolStripMenuItem: System.Windows.Forms.ToolStripMenuItem;
method InitializeComponent;
{$ENDREGION}
end;
implementation
{$REGION Windows Form Designer generated code}
method frmMain.InitializeComponent;
begin
var resources: System.ComponentModel.ComponentResourceManager
:= new System.ComponentModel.ComponentResourceManager(typeOf(frmMain));
self.button1 := new System.Windows.Forms.Button();
self.checkBox1 := new System.Windows.Forms.CheckBox();
self.menuStrip1 := new System.Windows.Forms.MenuStrip();
…
//
// checkBox1
//
self.checkBox1.AutoSize := true;
self.checkBox1.Location := new System.Drawing.Point(31, 59);
self.checkBox1.Name := 'checkBox1';
self.checkBox1.Size := new System.Drawing.Size(80, 17);
self.checkBox1.TabIndex := 1;
self.checkBox1.Text := 'checkBox1';
self.checkBox1.UseVisualStyleBackColor := true;
self.checkBox1.CheckedChanged +=
new System.EventHandler(@self.checkBox1_CheckedChanged);
//
// menuStrip1
//
…
end;
{$ENDREGION}
end.
Základní kód programu (ekvivalent obsahu .dpr):
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
class method Program.Main;
begin
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += OnThreadException;
using lMainForm := new frmMain do
Application.Run(lMainForm);
end;
Všimněte si použití using. Pro neznalé C#: using je konstrukce, která pro objekty implementující rozhraní IDisposable nahrazuje
tuto konstrukci
using f := new FileStream(…) do
begin
…
end;
místo
with f := new FileStream(…) do
try
…
finally
if (f is IDisposable) then
(f as IDisposable).Dispose();
end;
V .NET normálně uvolňuje objekty Garbage Collector (tj. žádné Free), pokud ale uznáte za vhodné mu pomoci, jde to právě přes using, kdy mu naznačíte, že po konci using může být objekt klidně uvolněn (resp. jeho prostředky už nebudou používány).