Jednou z inzerovaných vlastností nové verze Delphi Prism je možnost vložení C# kódu ve schránce jako by se jednalo o kód v Pascalu.
A ačkoliv v podstatě výlučně se starám o nativní Delphi, tak mne zajímalo, zda to funguje, protože jestli ano - tak je to správná cesta k prosazení Delphi Prism v .NET.

Funkce by měla být schopna vložit jak malý kód, tak celý unit.
Na začátek malý test
public static int giParse(string sValue, int iDefault)
{
// handle null extra
if (sValue == null)
return (iDefault);
try
{
return int.Parse(sValue);
}
catch
{
return iDefault;
}
}
a výsledek bez úprav je
method giParse(sValue: System.String; iDefault: System.Int32): System.Int32;
begin
// handle null extra
if sValue = nil then exit (iDefault);
try
exit System.Int32.Parse(sValue)
except begin
exit iDefault
end;
end
end;
což není špatné, takže
něco složitějšího
private void mHandleDownload(string sObjectType, string sProducerId)
{
int iProducerId = (int)giParse(sProducerId, 0);
if (iProducerId == 0)
{
Response.Redirect(Request.Path);
return;
}
List<string> oList = new List<string>();
SortedList<string, CProducerInfo> oProducers = new SortedList<string, CProducerInfo>();
mParseCSV(sObjectType, sProducerId, oList,
oProducers, System.Text.Encoding.Default);
string sProducer = sProducerId;
if (iProducerId == -1)
sProducer = sObjectType;
else
{
foreach (KeyValuePair<string, CProducerInfo> pair in oProducers)
{
if (iProducerId == pair.Value.iID)
{
sProducer = pair.Key;
break;
}
}
}
string s = "";
foreach (char c in sProducer)
{
if (((byte)c)< 128)
s += c;
}
string sFileName = sObjectType+"_"+s+".csv";
sFileName = sFileName.Replace(' ', '_');
string sZipFileName = sFileName+".zip";
Response.BufferOutput = true;
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition",
string.Format("attachment;filename={0}", sZipFileName));
ZipOutputStream oZIPStream = new ZipOutputStream(Response.OutputStream);
ZipEntry oEntry = new ZipEntry(sFileName);
oZIPStream.PutNextEntry(oEntry);
StreamWriter oStreamWriter = new StreamWriter(oZIPStream,
System.Text.Encoding.Default);
foreach (string sLine in oList)
oStreamWriter.WriteLine(sLine.Replace('^',';'));
oStreamWriter.Close();
oZIPStream.Finish();
oZIPStream.Close();
Response.End();
}
je transformováno na
method mHandleDownload(sObjectType: System.String; sProducerId: System.String);
begin
var iProducerId: System.Int32 := giParse(sProducerId, 0) as System.Int32;
if iProducerId = 0 then begin
Response.Redirect(Request.Path);
exit
end;
var oList: List<System.String> := new List<System.String>();
var oProducers: SortedList<System.String, CProducerInfo>
:= new SortedList<System.String, CProducerInfo>();
mParseCSV(sObjectType, sProducerId, oList, oProducers, System.Text.Encoding.Default);
var sProducer: System.String := sProducerId;
if iProducerId = -1 then sProducer := sObjectType
else begin
for each pair: KeyValuePair<System.String, CProducerInfo> in oProducers do begin
if iProducerId = pair.Value.iID then begin
sProducer := pair.Key;
break
end
end
end;
var s: System.String := '';
for each c: System.Char in sProducer do begin
if (c as System.Byte) < 128 then s := c
end;
var sFileName: System.String := sObjectType + '_' + s + '.csv';
sFileName := sFileName.Replace(' ', '_');
var sZipFileName: System.String := sFileName + '.zip';
Response.BufferOutput := true;
Response.Clear();
Response.ContentType := 'application/octet-stream';
Response.AddHeader('Content-Disposition',
System.String.Format('attachment;filename={0}', sZipFileName));
var oZIPStream: ZipOutputStream := new ZipOutputStream(Response.OutputStream);
var oEntry: ZipEntry := new ZipEntry(sFileName);
oZIPStream.PutNextEntry(oEntry);
var oStreamWriter: StreamWriter := new StreamWriter(oZIPStream,
System.Text.Encoding.Default);
for each sLine: System.String in oList do
oStreamWriter.WriteLine(sLine.Replace('^', ';'));
oStreamWriter.Close();
oZIPStream.Finish();
oZIPStream.Close();
Response.End()
end;
což bych tak asi nenapsal (hlavně System.String), ale vypadá to korektně.
Nikdo není bez chyby aneb problemy
Nakonec jsem program ale dostal (je to separované z větší funkce):
void mTest(string sPath, System.Text.Encoding oEnc, List<string> oFilteredList)
{
using (StreamReader sr = new StreamReader(sPath, oEnc))
{
string sLine;
while ((sLine = sr.ReadLine()) != null)
{
iLine += 1;
if (iLine == 1)
{
continue; // ignore header - first line
}
string[] sItems = sLine.Split('|');
if (sItems.Length < 3)
continue;
oFilteredList.Add(sLine)
}
}
}
je transformováno na
method mTest(sPath: System.String; oEnc: System.Text.Encoding;
oFilteredList: List<System.String>);
begin
using sr: StreamReader := new StreamReader(sPath, oEnc) do begin
var sLine: System.String;
while (sLine := sr.ReadLine()) <> nil do begin // <<<< Chyba
iLine := 1; // <<<Chyba
if iLine = 1 then begin
continue
end// ignore header - first line
;
var sItems: array of System.String := sLine.Split('|');
if sItems.Length < 3 then continue;
oFilteredList.Add(sLine)
end
end
end;
což mne přivedlo na
void mTest2()
{
int i = 1;
i += 1;
int z = i++;
int zz = ++i;
}
se špatným výsledkem
method ConsoleApp.mTest2();
begin
var i: System.Int32 := 1;
i := 1; // velká chyba
var z: System.Int32 := {POST}inc(i); // to člověka trkne
var zz: System.Int32 := inc(i)
end;
Závěr
Závěrem mini testu je, že se jedná o užitečnou funkci, která může velmi pomoci při použití cizího kódu, ale
člověk může narazit a to celkem rychle. Ale je to krok správným směrem.