Delphi Prism 2011 - vložit C# jako Pascal

vložil Radek Červinka 27. července 2010 01:43

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.

Delphi Prism - C# kód

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

    1method mHandleDownload(sObjectType: System.String; sProducerId: System.String);
    2begin
    3  var iProducerId: System.Int32 := giParse(sProducerId, 0) as System.Int32;
    4  if iProducerId = 0 then begin
    5    Response.Redirect(Request.Path);
    6    exit
    7  end;
    8  var oList: List<System.String> := new List<System.String>();
    9  var oProducers: SortedList<System.String, CProducerInfo> 
   10     := new SortedList<System.String, CProducerInfo>();
   11  mParseCSV(sObjectType, sProducerId, oList, oProducers, System.Text.Encoding.Default);
   12  var sProducer: System.String := sProducerId;
   13  if iProducerId = -1 then    sProducer := sObjectType
   14  else begin
   15    for each pair: KeyValuePair<System.String, CProducerInfo> in oProducers do begin
   16      if iProducerId = pair.Value.iID then begin
   17        sProducer := pair.Key;
   18        break
   19      end
   20    end
   21  end;
   22  var s: System.String := '';
   23
   24  for each c: System.Char in sProducer do begin
   25    if (c as System.Byte) < 128 then      s := c
   26  end;
   27
   28  var sFileName: System.String := sObjectType + '_' + s + '.csv';
   29  sFileName := sFileName.Replace(' ', '_');
   30  var sZipFileName: System.String := sFileName + '.zip';
   31
   32  Response.BufferOutput := true;
   33  Response.Clear();
   34  Response.ContentType := 'application/octet-stream';
   35  Response.AddHeader('Content-Disposition', 
   36       System.String.Format('attachment;filename={0}', sZipFileName));
   37
   38  var oZIPStream: ZipOutputStream := new ZipOutputStream(Response.OutputStream);
   39  var oEntry: ZipEntry := new ZipEntry(sFileName);
   40  oZIPStream.PutNextEntry(oEntry);
   41  var oStreamWriter: StreamWriter := new StreamWriter(oZIPStream,
   42    System.Text.Encoding.Default);
   43  for each sLine: System.String in oList do
   44    oStreamWriter.WriteLine(sLine.Replace('^', ';'));
   45  oStreamWriter.Close();
   46  oZIPStream.Finish();
   47  oZIPStream.Close();
   48  Response.End()
   49end;

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

    1method mTest(sPath: System.String; oEnc: System.Text.Encoding;
    2   oFilteredList: List<System.String>);
    3begin
    4  using sr: StreamReader := new StreamReader(sPath, oEnc) do begin
    5    var sLine: System.String;
    6    while (sLine := sr.ReadLine()) <> nil do begin   // <<<< Chyba
    7      iLine := 1;               // <<<Chyba
    8      if iLine = 1 then begin
    9        continue
   10      end// ignore header - first line
   11;
   12      var sItems: array of System.String := sLine.Split('|');
   13      if sItems.Length < 3 then        continue;
   14      oFilteredList.Add(sLine)
   15    end
   16  end
   17end;

což mne přivedlo na

void mTest2()
{
  int i = 1;
  i += 1;
  int z = i++;
  int zz = ++i;
}

se špatným výsledkem

    1method ConsoleApp.mTest2();
    2begin
    3  var i: System.Int32 := 1;
    4  i := 1; // velká chyba
    5  var z: System.Int32 := {POST}inc(i); // to člověka trkne
    6  var zz: System.Int32 := inc(i)
    7end;

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.


Nabízíme Delphi školení a konzultace na různá témata, primárně ve Vaší firmě.

Tagy:

Recenze

Komentáře

29.7.2010 11:52:43 #

cerda

Zni to zajimave, ale neprevadeni zakladniho operatoru += je podstatna chyba, copak by asi system rekl treba na &= ci ^= :)

cerda

Komentování ukončeno

Naše nabídka

Partial English version.

MVP
Ing. Radek Červinka - Embarcadero MVP
profil na linkedin, Twitter:@delphicz

Nabízím placené poradenství a konzultace v oblasti programování a vývoje SW.
Dále nabízíme i vývoj speciálního software na zakázku.

Neváhejte nás kontaktovat (i ohledně reklamy nebo burzy práce).

Pokud chcete podpořit tento server libovolnou částkou, můžete použít PayPal. Moc děkuji.

Delphi Certified Developer

O Delphi.cz

Delphi je jediný moderní RAD nástroj podporující tvorbu nativních aplikací pro platformu Win32, Win64 , Mac OSX a na iPhone a Android (s výhledem na další platformy díky FireMonkey) na současném trhu (včetně Windows 8.1).

V současnosti je světová komunita přes dva miliónů vývojářů.

Delphi.cz je nezávislý portál pro uživatele Delphi. Portál není koncipován pro úplné začátečníky, i když i ti se zde nebudou nudit, ale spíše na programátory, kteří již něco znají a chtějí své znalosti dále rozvíjet a sledovat novinky.

Anketa

Poslední komentáře

Comment RSS