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.
loBridge = NEWOBJECT("FoxBridge", "FoxBridge.prg")
IF !loBridge.Activate(lcJwt)
? loBridge.GetLastError()
RETURN
ENDIFGrundstufe: 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.
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.
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.
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.
ENDIFMittelstufe: 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.
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.
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().
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.
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.
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
ENDTRYBeispiel 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.
* 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.
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.
* 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.
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.
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
ENDTRYBeispiel 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.
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.
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.
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.
* 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.
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.
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.
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 ->