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

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.

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

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).

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.

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.

Poslední komentáře

Comment RSS