Examples
20 progressive examples taking you from .NET basics to real-world use cases: generic collections, async/await, HttpClient and more. Each example is self-contained and ready to paste into your project.
loBridge = NEWOBJECT("FoxBridge", "FoxBridge.prg")
IF !loBridge.Activate(lcJwt)
? loBridge.GetLastError()
RETURN
ENDIFBasic level: first steps
Example 1: StringBuilder, your first .NET object
StringBuilder is the best starting point: simple, predictable and demonstrates the full cycle of Create, call methods, get result.
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.Example 2: Uri, inspecting a URL
System.Uri breaks a URL into its parts (host, port, path, query). Demonstrates the use of Qualified Assembly Names (AQN) with the comma.
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.Example 3: LoadAssembly, using your own DLL
The real power of FoxBridge: load a DLL you compiled yourself in C# or VB.NET and call its classes as if they were native VFP objects.
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.
ENDIFIntermediate level: collections, statics and exceptions
Example 4: List<String>, generic lists
FoxBridge automatically converts List<T> to a proxy with Add, Remove, Item and Count methods. Indexing is 1-based, like 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.Example 5: DirectoryInfo, listing files
GetFiles() returns an array of FileInfo objects. Each element is a FoxBridge proxy with its own properties. We use GetObject(i) to access each element.
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.Example 6: Dictionary<String, String>, key-value
.NET dictionaries in FoxBridge use Set, Get, ContainsKey and Remove. Mind the name: it is ContainsKey, not Contains. When the value is a complex object, use GetObject() instead of 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.Example 7: Overload resolution, the Binder in action
VFP has only one numeric type (Double). FoxBridge automatically detects the correct overload for each call. Here we test it with Append(), which has 18 overloads in .NET.
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.Example 8: Catching .NET exceptions
When a .NET method throws an exception, FoxBridge converts it to a VFP error that you can catch with TRY/CATCH. The message includes the original exception and 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
ENDTRYExample 9: Static members, File, Guid, Environment
Classes like System.IO.File, System.Guid and System.Environment are fully static. loBridge.Static() returns a proxy that exposes all their methods and properties.
* 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.Example 10: Read/write static properties
Some static properties are read/write (get+set). FoxBridge treats them like normal proxy properties.
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.Advanced level: performance, binaries and async
Example 11: Enums as numbers, File.Open with FileMode and FileAccess
VFP has no enums, but .NET uses them constantly. FoxBridge accepts the integer value of the enum directly. Consult MSDN documentation for numeric values.
* 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.Example 12: Performance stress, 1000 calls to System.Math
FoxBridge caches method resolution after the first call. Subsequent invocations of the same method are significantly faster.
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.Example 13: Chained nested properties
When a property returns another object, FoxBridge automatically wraps it in a new proxy. You can chain accesses with dot notation normally.
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
ENDTRYExample 14: Handling null values
FoxBridge translates VFP .NULL. to .NET null when the method accepts it. When the method expects a value type (int, bool), it will throw an exception that you can catch normally.
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.Example 15: Large strings, data transfer
FoxBridge handles multi-megabyte strings without issues. The bridge copies memory once in each direction, so time scales linearly with size.
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.Example 16: Dictionary with object values
When the dictionary value is a .NET object (not a scalar), use GetObject() to retrieve it as a FoxBridge proxy. You can compare objects by handle.
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.Example 17: DateTime, creating and manipulating dates
System.DateTime is the one case where FoxBridge does NOT hand you a proxy: dates cross converted, so what you get is a VFP DATETIME and you handle it with YEAR(), MONTH() and the usual arithmetic. The same happens the other way round, which is why you can pass a VFP date to a .NET method that expects a 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.Example 18: Transparent async, Task.Delay
When a .NET method returns a Task (async), FoxBridge automatically waits for it before continuing. From VFP it looks like a normal synchronous call.
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.Example 19: HttpClient, downloading web content
HttpClient is an async .NET class. FoxBridge makes it synchronous automatically. This replaces WinHTTP, XMLHTTP and any other COM dependency you use today.
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.Example 20: HttpClient with POST and JSON, calling a REST API
The most complete use case: build a JSON payload with StringBuilder, send it with HttpClient.PostAsync and read the response. This is a complete REST client written 100% in VFP.
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.Back to API reference: API Reference ->