IR
irwinrodriguez.dev
Back to docs

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.

About initialization All examples assume loBridge is already initialized. Run this once at startup:
loBridge = NEWOBJECT("FoxBridge", "FoxBridge.prg")

Basic 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       && 28
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:MiAppinMiLogica.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

Intermediate 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/Contains/Remove. 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.Contains("nombre")   && .T.
? "Valor:", loDict.Get("nombre")                     && "Irwin Rodriguez"

loDict.Remove("lang")
? "Contiene 'lang' tras Remove:", loDict.Contains("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 envia Double, .NET resuelve a Append(int)

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
ENDTRY

Example 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:oxbridge_test.txt", "Prueba de escritura estatica")
? loFile.Exists("C:oxbridge_test.txt")   && .T.
? loFile.ReadAllText("C:oxbridge_test.txt")
loFile.Delete("C:oxbridge_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:oxbridge_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
ENDTRY

Example 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 String: aceptado (String es referencia)
TRY
    loSB.Append(.NULL.)
    ? "OK: StringBuilder acepta null en lugar de String"
CATCH TO loEx
    ? "Error inesperado:", 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 allows creating precise dates and passing them to .NET methods that expect them. FoxBridge automatically converts VFP DateTime to .NET DateTime.

loDt  = loBridge.Static("System.DateTime")
loNow = loDt.Now

? "Fecha/hora actual:", loNow.ToString()
? "Ano:", loNow.Year
? "Mes:", loNow.Month
? "Dia:", loNow.Day

* Sumar dias
loManana = loNow.AddDays(1)
? "Manana:", loManana.ToString()

* Usar DateTime en un metodo que lo espera
loFile = loBridge.Static("System.IO.File")
SET SAFETY OFF
StrToFile("prueba", "fb_dt.tmp")
loFile.SetCreationTime("fb_dt.tmp", loNow)
loInfo = loBridge.Create("System.IO.FileInfo", "fb_dt.tmp")
? "Fecha de creacion:", loInfo.CreationTime
Erase fb_dt.tmp

loDt   = .NULL.
loNow  = .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")
loContent = loBridge.Static("System.Net.Http.StringContent, System.Net.Http")

* Construir JSON con StringBuilder
loSB = loBridge.Create("System.Text.StringBuilder")
loSB.Append("{")
loSB.Append("""title"": ""FoxBridge es increible"",")
loSB.Append("""body"": ""Prueba de POST desde VFP"",")
loSB.Append("""userId"": 1")
loSB.Append("}")
lcJson = loSB.ToString()
loSB   = .NULL.

TRY
    * Crear el contenido HTTP con encoding y Content-Type
    loBody = loBridge.Create("System.Net.Http.StringContent, System.Net.Http", ;
        lcJson, .NULL., "application/json")

    * Enviar POST (async, FoxBridge espera)
    loResp = loHttp.PostAsync("https://jsonplaceholder.typicode.com/posts", loBody)

    * Leer el resultado
    lcRespuesta = loResp.Content.ReadAsStringAsync()
    ? "Respuesta del servidor:"
    ? lcRespuesta

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

loHttp    = .NULL.

Back to API reference: API Reference ->