IR
irwinrodriguez.dev
Zurück zur Dokumentation

Beispiele

20 fortschreitende Beispiele, die Sie von .NET-Grundlagen bis zu realen Anwendungsfallen fuhren: generische Sammlungen, async/await, HttpClient und mehr. Jedes Beispiel ist in sich geschlossen und bereit zum Einfügen in Ihr Projekt.

Über die Initialisierung Alle Beispiele setzen voraus, dass loBridge bereits initialisiert UND FREIGESCHALTET ist. Ohne Activate() funktioniert keines: jeder Aufruf antwortet mit „FoxBridge is not activated“. Führen Sie dies einmal beim Start aus:
Bridge erzeugen und freischalten (einmal beim Start)
loBridge = NEWOBJECT("FoxBridge", "FoxBridge.prg")
IF !loBridge.Activate(lcJwt)
    ? loBridge.GetLastError()
    RETURN
ENDIF

Grundstufe: erste Schritte

Beispiel 1: StringBuilder, Ihr erstes .NET-Objekt

StringBuilder ist der beste Ausgangspunkt: einfach, vorhersehbar und demonstriert den vollständigen Zyklus von Create bis Ergebnis.

StringBuilder: eine Zeichenkette in .NET aufbauen
loBuilder = loBridge.Create("System.Text.StringBuilder", "Hola ")
loBuilder.Append("mundo ")
loBuilder.Append("desde FoxBridge!")
? loBuilder.ToString()   && "Hola mundo desde FoxBridge!"
? loBuilder.Length       && 27
loBuilder = .NULL.

Beispiel 2: Uri, eine URL analysieren

System.Uri zerlegt eine URL in ihre Bestandteile. Demonstriert die Verwendung von qualifizierten Assembly-Namen (AQN) mit Komma.

System.Uri: eine URL in ihre Bestandteile zerlegen
loUri = loBridge.Create("System.Uri, System", "https://api.miempresa.com:8080/v1/clientes?estado=activo")
? "Host:  ", loUri.Host           && "api.miempresa.com"
? "Puerto:", loUri.Port           && 8080
? "Ruta:  ", loUri.AbsolutePath   && "/v1/clientes"
? "Query: ", loUri.Query          && "?estado=activo"
loUri = .NULL.

Beispiel 3: LoadAssembly, eigene DLL verwenden

Die wahre Starke von FoxBridge: eine eigene in C# oder VB.NET kompilierte DLL laden und ihre Klassen wie native VFP-Objekte aufrufen.

LoadAssembly: die Summe mit MwSt. aus Ihrer DLL berechnen
llOk = loBridge.LoadAssembly("C:\MiApp\bin\MiLogica.dll")
IF llOk
    loFactura = loBridge.Create("MiLogica.Facturacion", 0.16)  && IVA 16%
    lnTotal   = loFactura.CalcularTotal(1000.00)
    ? "Total con IVA:", lnTotal   && 1160.00
    loFactura = .NULL.
ENDIF

Mittelstufe: Sammlungen, Statische und Ausnahmen

Beispiel 4: List<String>, generische Listen

FoxBridge konvertiert List<T> automatisch in einen Proxy mit den Methoden Add, Remove, Item und Count. Die Indizierung ist 1-basiert wie in VFP.

List<String>: Elemente hinzufügen, durchlaufen und entfernen
loLista = loBridge.Create("List<String>")
loLista.Add("Visual FoxPro")
loLista.Add("C#")
loLista.Add("F#")
loLista.Add("Go")

? "Total:", loLista.Count()    && 4
? "Tercero:", loLista.Item(3)  && "F#"

* Recorrer
For i = 1 to loLista.Count()
  ? Transform(i) + ". " + loLista.Item(i)
Next

loLista.Remove("Go")
? "Despues de Remove:", loLista.Count()   && 3
loLista = .NULL.

Beispiel 5: DirectoryInfo, Dateien auflisten

GetFiles() gibt ein Array von FileInfo-Objekten zurück. Jedes Element ist ein FoxBridge-Proxy mit eigenen Eigenschaften. Wir verwenden GetObject(i) für den Zugriff.

DirectoryInfo: Name, Größe und Endung jeder Datei
loDir   = loBridge.Create("System.IO.DirectoryInfo", "C:\Windows")
loFiles = loDir.GetFiles()

? "Archivos encontrados:", loFiles.Count()

For i = 1 to Min(5, loFiles.Count())
    loFile = loFiles.GetObject(i)
    ? "Nombre:  " + loFile.Name
    ? "Tamano:  " + Transform(loFile.Length) + " bytes"
    ? "Extension: " + loFile.Extension
    loFile = .NULL.
Next

loFiles = .NULL.
loDir   = .NULL.

Beispiel 6: Dictionary<String, String>, Schlüssel-Wert

.NET-Dictionaries verwenden in FoxBridge Set, Get, ContainsKey und Remove. Achten Sie auf den Namen: es heißt ContainsKey, nicht Contains. Ist der Wert ein komplexes Objekt, verwenden Sie GetObject() statt Get().

Dictionary<String, String>: Schlüssel speichern, abfragen und entfernen
loDict = loBridge.Create("Dictionary<String, String>")
loDict.Set("nombre", "Irwin Rodriguez")
loDict.Set("pais",   "Mexico")
loDict.Set("lang",   "Visual FoxPro")

? "Contiene 'nombre':", loDict.ContainsKey("nombre")   && .T.
? "Valor:", loDict.Get("nombre")                        && "Irwin Rodriguez"

loDict.Remove("lang")
? "Contiene 'lang' tras Remove:", loDict.ContainsKey("lang")   && .F.

loDict = .NULL.

Beispiel 7: Überladungsauflösung, der Binder in Aktion

VFP hat nur einen numerischen Typ (Double). FoxBridge erkennt automatisch die richtige Uberladung für jeden Aufruf. Hier testen wir das mit Append(), das 18 Uberladungen in .NET hat.

StringBuilder.Append: eine Überladung für jeden VFP-Typ
loSB = loBridge.Create("System.Text.StringBuilder")

loSB.Append("Entero: ")
loSB.Append(100)        && VFP manda Double y el Binder busca la firma
                        && exacta: resuelve a Append(double)

loSB.Append(" | Booleano: ")
loSB.Append(.T.)        && VFP envia Logical, .NET resuelve a Append(bool)

loSB.Append(" | Double: ")
loSB.Append(45.67)      && .NET resuelve a Append(double)

? loSB.ToString()   && "Entero: 100 | Booleano: True | Double: 45.67"
loSB = .NULL.

Beispiel 8: .NET-Ausnahmen abfangen

Wenn eine .NET-Methode eine Ausnahme auslöst, konvertiert FoxBridge sie in einen VFP-Fehler, den Sie mit TRY/CATCH abfangen können. Die Meldung enthält die ursprüngliche Ausnahme und InnerException.

Die Ausnahme einer ungültigen URL mit TRY/CATCH abfangen
TRY
    * Un URI invalido lanza FormatException en .NET
    loUri = loBridge.Create("System.Uri, System", "esto no es una URL")
    ? "ERROR: no deberia llegar aqui"
CATCH TO loEx
    ? "Excepcion capturada:"
    ? loEx.Message   && describe el error de .NET
ENDTRY

Beispiel 9: Statische Member, File, Guid, Environment

Klassen wie System.IO.File, System.Guid und System.Environment sind vollständig statisch. loBridge.Static() gibt einen Proxy zurück, der alle ihre Methoden und Eigenschaften bereitstellt.

File, Guid und Environment: statische Member
* Escribir y leer un archivo
loFile = loBridge.Static("System.IO.File")
loFile.WriteAllText("C:\foxbridge_test.txt", "Prueba de escritura estatica")
? loFile.Exists("C:\foxbridge_test.txt")   && .T.
? loFile.ReadAllText("C:\foxbridge_test.txt")
loFile.Delete("C:\foxbridge_test.txt")

* Generar un GUID unico
loGuid = loBridge.Static("System.Guid")
loNewGuid = loGuid.NewGuid()
? "GUID nuevo:", loNewGuid.ToString()   && "a1b2c3d4-..."

* Informacion del sistema
loEnv = loBridge.Static("System.Environment")
? "Maquina:     ", loEnv.MachineName
? "Version OS:  ", loEnv.OSVersion.ToString()
? "Procesadores:", loEnv.ProcessorCount

loFile = .NULL.
loGuid = .NULL.
loEnv  = .NULL.

Beispiel 10: Lese-/Schreib-Statische-Eigenschaften

Einige statische Eigenschaften sind lese-/schreibbar (get+set). FoxBridge behandelt sie wie normale Proxy-Eigenschaften.

Environment.CurrentDirectory: Arbeitsverzeichnis ändern und wiederherstellen
loEnv = loBridge.Static("System.Environment")
lcDirActual = loEnv.CurrentDirectory
? "Directorio actual:", lcDirActual

* Cambiar el directorio de trabajo
loEnv.CurrentDirectory = "C:\"
? "Nuevo directorio:", loEnv.CurrentDirectory   && "C:\"

* Restaurar
loEnv.CurrentDirectory = lcDirActual
loEnv = .NULL.

Fortgeschrittene Stufe: Leistung, Binardaten und Async

Beispiel 11: Enums als Zahlen, File.Open mit FileMode und FileAccess

VFP hat keine Enums, aber .NET verwendet sie standig. FoxBridge akzeptiert den ganzzahligen Enum-Wert direkt. Konsultieren Sie die MSDN-Dokumentation für numerische Werte.

File.Open mit FileMode und FileAccess als Zahlen
* FileMode.Open = 3, FileAccess.Read = 1
lcPath = "C:\foxbridge_enum_test.txt"
SET SAFETY OFF
StrToFile("datos de prueba", lcPath)

loFile = loBridge.Static("System.IO.File")

TRY
    loStream = loFile.Open(lcPath, 3, 1)  && Open para lectura
    IF !IsNull(loStream)
        ? "Stream abierto. Longitud:", loStream.Length
        loStream.Close()
        loStream = .NULL.
    ENDIF
CATCH TO loEx
    ? "Error:", loEx.Message
ENDTRY

IF File(lcPath)
    Erase (lcPath)
ENDIF

loFile = .NULL.

Beispiel 12: Leistungstest, 1000 Aufrufe an System.Math

FoxBridge speichert die Methodenauflosung nach dem ersten Aufruf zwischen. Folgende Aufrufe derselben Methode sind deutlich schneller.

1000 Aufrufe an System.Math hintereinander messen
loMath = loBridge.Static("System.Math")
lnStart = Seconds()

For i = 1 to 1000
    lnVal = loMath.Max(i, 500)
    lnVal = loMath.Sqrt(lnVal)
    lnVal = loMath.Round(lnVal, 2)
Next

? "1000 llamadas en:", Seconds() - lnStart, "segundos"
? "Ultimo valor:", lnVal

loMath = .NULL.

Beispiel 13: Verkettete geschachtelte Eigenschaften

Wenn eine Eigenschaft ein anderes Objekt zurückgibt, verpackt FoxBridge es automatisch in einen neuen Proxy. Sie können Zugriffe normal mit Punkt verketten.

Der aktuelle Prozess und sein Hauptmodul, Eigenschaft für Eigenschaft
TRY
    loProcess = loBridge.Static("System.Diagnostics.Process, System")
    loProc    = loProcess.GetCurrentProcess()

    ? "Proceso:", loProc.ProcessName

    loModule = loProc.MainModule
    ? "Modulo: ", loModule.ModuleName
    ? "Ruta:   ", loModule.FileName

    loModule = .NULL.
    loProc   = .NULL.
CATCH TO loEx
    ? "Error:", loEx.Message
ENDTRY

Beispiel 14: Umgang mit Nullwerten

FoxBridge übersetzt VFP .NULL. in .NET null, wenn die Methode es akzeptiert. Wenn die Methode einen Werttyp erwartet (int, bool), wird eine Ausnahme ausgelöst, die Sie normal abfangen können.

.NULL. nach .NET: eine Liste nimmt es an, ein int nicht
loSB = loBridge.Create("System.Text.StringBuilder")

* .NULL. a un parametro de tipo referencia: aceptado.
*
* Ojo con el caso de Append: tiene varias sobrecargas de referencia
* (string, object, char[], StringBuilder...), y el Binder resuelve por
* coincidencia exacta, sin heuristicas, asi que un null a secas puede
* quedar ambiguo. Cuando quieras un null de un tipo concreto, pasalo
* por una variable del tipo que sea, o usa un metodo de una sola
* sobrecarga.
TRY
    loLista = loBridge.Create("List<String>")
    loLista.Add(.NULL.)
    ? "OK: la lista acepta null como elemento"
CATCH TO loEx
    ? "Error:", loEx.Message
ENDTRY

* .NULL. a un parametro int: error controlado
TRY
    loSB.EnsureCapacity(.NULL.)
CATCH TO loEx
    ? "Error esperado (int no acepta null):", loEx.Message
ENDTRY

loSB = .NULL.

Beispiel 15: Große Strings, Datentransfer

FoxBridge verarbeitet Strings von mehreren Megabyte ohne Probleme. Die Bridge kopiert den Speicher einmal in jede Richtung, daher skaliert die Zeit linear mit der Größe.

1 MB Text zwischen VFP und .NET senden und empfangen
lcGrande = Replicate("X", 1024 * 1024)  && 1 MB

loSB = loBridge.Create("System.Text.StringBuilder")

lnStart = Seconds()
loSB.Append(lcGrande)
? "Envio 1MB a .NET en:", Seconds() - lnStart, "seg"

lnStart = Seconds()
lcRecibido = loSB.ToString()
? "Recibo 1MB desde .NET en:", Seconds() - lnStart, "seg"

? "Longitud recibida:", Len(lcRecibido)  && 1048576
? "Objetos en heap .NET:", loBridge.GetObjectCount()

loSB = .NULL.

Beispiel 16: Dictionary mit Objekt-Werten

Wenn der Dictionary-Wert ein .NET-Objekt ist (kein Skalar), verwenden Sie GetObject() um es als FoxBridge-Proxy abzurufen. Sie können Objekte per Handle vergleichen.

Ein StringBuilder als Wert eines Dictionary
loDict = loBridge.Create("Dictionary<String, System.Text.StringBuilder>")

* Insertar un StringBuilder como valor
loSB = loBridge.Create("System.Text.StringBuilder", "Contenido inicial")
loDict.Set("doc1", loSB)

* Recuperar y modificar
loRecuperado = loDict.GetObject("doc1")
loRecuperado.Append(" — modificado!")
? loRecuperado.ToString()   && "Contenido inicial — modificado!"

* Es el mismo objeto?
? loSB.GetHandle() == loRecuperado.GetHandle()   && .T.

loDict       = .NULL.
loSB         = .NULL.
loRecuperado = .NULL.

Beispiel 17: DateTime, Datum erstellen und manipulieren

System.DateTime ist der Fall, in dem FoxBridge KEINEN Proxy liefert: Datumswerte werden umgewandelt, Sie erhalten also ein VFP-DATETIME und behandeln es mit YEAR(), MONTH() und der gewohnten Arithmetik. In der Gegenrichtung gilt dasselbe, und deshalb können Sie einem .NET-Methodenaufruf, der ein DateTime erwartet, ein VFP-Datum übergeben.

DateTime: .NET-Datumswerte als VFP-DATETIME
* System.DateTime NO cruza como proxy: FoxBridge lo convierte a un
* DATETIME de VFP (por OLE Automation Date) en los dos sentidos. Asi
* que lo que vuelve es un valor de tipo T, y se trata con las funciones
* de fecha de VFP de toda la vida.
loDt    = loBridge.Static("System.DateTime")
ltAhora = loDt.Now

? "Fecha y hora:", ltAhora        && un DATETIME de VFP
? "Ano:",  YEAR(ltAhora)
? "Mes:",  MONTH(ltAhora)
? "Dia:",  DAY(ltAhora)

* La aritmetica tambien es la de VFP, en segundos
ltManana = ltAhora + 86400

* Y de vuelta: un DATETIME de VFP entra tal cual en un metodo .NET
* que espera un DateTime.
SET SAFETY OFF
STRTOFILE("prueba", "fb_dt.tmp")

loFile = loBridge.Static("System.IO.File")
loFile.SetCreationTime("fb_dt.tmp", ltManana)

loInfo = loBridge.Create("System.IO.FileInfo", "fb_dt.tmp")
? "Fecha de creacion:", loInfo.CreationTime   && otro DATETIME de VFP
ERASE fb_dt.tmp

loDt   = .NULL.
loFile = .NULL.
loInfo = .NULL.

Beispiel 18: Transparentes Async, Task.Delay

Wenn eine .NET-Methode einen Task zurückgibt (async), wartet FoxBridge automatisch darauf, bevor es weitermacht. Aus VFP-Sicht sieht es wie ein normaler synchroner Aufruf aus.

Task.Delay: auf eine Async-Task ohne zusätzlichen Code warten
loTask = loBridge.Static("System.Threading.Tasks.Task")

? "Llamando Task.Delay(2000) — espera 2 segundos..."
lnStart = Seconds()

loTask.Delay(2000)   && FoxBridge espera automaticamente

? "Tiempo transcurrido:", Seconds() - lnStart, "seg"  && ~2 seg
? "El bridge espero sin necesidad de codigo adicional"

loTask = .NULL.

Beispiel 19: HttpClient, Webinhalt herunterladen

HttpClient ist eine asynchrone .NET-Klasse. FoxBridge macht sie automatisch synchron. Dies ersetzt WinHTTP, XMLHTTP und alle anderen COM-Abhangigkeiten, die Sie heute verwenden.

HttpClient: eine Seite per GET herunterladen
loHttp = loBridge.Create("System.Net.Http.HttpClient, System.Net.Http")

TRY
    lcUrl  = "https://httpbin.org/get"
    ? "Descargando:", lcUrl

    lcJson = loHttp.GetStringAsync(lcUrl)   && async, FoxBridge espera

    ? "Recibidos:", Len(lcJson), "bytes"
    ? "Primeros 200 chars:"
    ? Left(lcJson, 200)
CATCH TO loEx
    ? "Error de red:", loEx.Message
ENDTRY

loHttp = .NULL.

Beispiel 20: HttpClient mit POST und JSON, REST-API aufrufen

Der vollstandigste Anwendungsfall: JSON-Payload mit StringBuilder erstellen, mit HttpClient.PostAsync senden und die Antwort lesen. Das ist ein vollständiger REST-Client, der 100% in VFP geschrieben ist.

HttpClient: JSON per POST an eine REST-API senden
loHttp = loBridge.Create("System.Net.Http.HttpClient, System.Net.Http")

* Construir el JSON con StringBuilder
loSB = loBridge.Create("System.Text.StringBuilder")
loSB.Append("{")
loSB.Append("""title"": ""Alta de cliente"",")
loSB.Append("""body"": ""Enviado desde VFP"",")
loSB.Append("""userId"": 1")
loSB.Append("}")
lcJson = loSB.ToString()
loSB   = .NULL.

TRY
    * Encoding.UTF8 es una propiedad estatica, y devuelve un OBJETO.
    * Hay que pasarlo como tal: con .NULL. el Binder no encuentra el
    * constructor StringContent(string, Encoding, string).
    loEnc  = loBridge.Static("System.Text.Encoding")
    loUTF8 = loEnc.UTF8

    loBody = loBridge.Create("System.Net.Http.StringContent, System.Net.Http", ;
        lcJson, loUTF8, "application/json")

    * POST. Es async, y FoxBridge espera la Task por ti.
    loResp = loHttp.PostAsync("https://jsonplaceholder.typicode.com/posts", loBody)

    * Content es un proxy; ReadAsStringAsync() tambien se espera sola.
    loContent   = loResp.Content
    lcRespuesta = loContent.ReadAsStringAsync()
    ? "Respuesta del servidor:"
    ? lcRespuesta

    loContent = .NULL.
    loBody    = .NULL.
    loResp    = .NULL.
    loUTF8    = .NULL.
    loEnc     = .NULL.
CATCH TO loEx
    ? "Error:", loEx.Message
ENDTRY

loHttp = .NULL.

Zurück zur API-Referenz: API-Referenz ->