IR
irwinrodriguez.dev
Volver a documentacion

Ejemplos

20 ejemplos progresivos que te llevan desde lo mas basico de .NET hasta casos de uso reales: colecciones genericas, async/await, HttpClient y mas. Cada ejemplo es autocontenido y listo para pegar en tu proyecto.

Sobre la inicializacion Todos los ejemplos asumen que loBridge ya esta inicializado. Ejecuta esto una sola vez al inicio:
loBridge = NEWOBJECT("FoxBridge", "FoxBridge.prg")

Nivel basico: los primeros pasos

Ejemplo 1: StringBuilder — tu primer objeto .NET

StringBuilder es el mejor punto de partida: es simple, predecible y demuestra el ciclo completo de Create → llamar metodos → obtener resultado.

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.

Ejemplo 2: Uri — inspeccionar una URL

System.Uri descompone una URL en sus partes (host, puerto, ruta, query). Demuestra el uso de Qualified Assembly Names (AQN) con la coma.

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.

Ejemplo 3: LoadAssembly — usar tu propia DLL

El verdadero poder de FoxBridge: cargar una DLL que tu mismo compilaste en C# o VB.NET y llamar sus clases como si fueran objetos VFP nativos.

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

Nivel intermedio: colecciones, estaticos y excepciones

Ejemplo 4: List<String> — listas genericas

FoxBridge convierte automaticamente List<T> en un proxy con los metodos Add, Remove, Item y Count. La indexacion es base-1, como en 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.

Ejemplo 5: DirectoryInfo — listar archivos

GetFiles() devuelve un array de objetos FileInfo. Cada elemento es un proxy FoxBridge con sus propias propiedades. Usamos GetObject(i) para acceder a cada elemento.

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.

Ejemplo 6: Dictionary<String, String> — clave-valor

Los diccionarios .NET en FoxBridge usan Set/Get/Contains/Remove. Cuando el valor es un objeto complejo, usa GetObject() en lugar de 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.

Ejemplo 7: Resolucion de sobrecargas — el Binder en accion

VFP solo tiene un tipo numerico (Double). FoxBridge detecta automaticamente el overload correcto para cada llamada. Aqui lo ponemos a prueba con Append(), que tiene 18 sobrecargas en .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.

Ejemplo 8: Captura de excepciones .NET

Cuando un metodo .NET lanza una excepcion, FoxBridge la convierte en un error VFP que puedes capturar con TRY/CATCH. El mensaje incluye la excepcion original y la 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

Ejemplo 9: Miembros estaticos — File, Guid, Environment

Clases como System.IO.File, System.Guid y System.Environment son completamente estaticas. loBridge.Static() devuelve un proxy que expone todos sus metodos y propiedades.

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

Ejemplo 10: Propiedades estaticas de lectura/escritura

Algunas propiedades estaticas son de lectura/escritura (get+set). FoxBridge las trata como propiedades normales del proxy.

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.

Nivel avanzado: rendimiento, binarios y async

Ejemplo 11: Enums como numeros — File.Open con FileMode y FileAccess

VFP no tiene enums, pero .NET los usa constantemente. FoxBridge acepta el valor entero del enum directamente. Consulta la documentacion de MSDN para ver los valores numericos.

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

Ejemplo 12: Stress de rendimiento — 1000 llamadas a System.Math

FoxBridge cachea la resolucion de metodos tras la primera llamada. Las siguientes invocaciones al mismo metodo son significativamente mas rapidas.

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.

Ejemplo 13: Cadenas de propiedades anidadas

Cuando una propiedad devuelve otro objeto, FoxBridge lo envuelve automaticamente en un nuevo proxy. Puedes encadenar accesos con punto normalmente.

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

Ejemplo 14: Manejo de valores nulos

FoxBridge traduce .NULL. de VFP a null de .NET cuando el metodo lo acepta. Cuando el metodo espera un tipo por valor (int, bool), lanzara excepcion, que puedes capturar normalmente.

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.

Ejemplo 15: Strings grandes — transferencia de datos

FoxBridge maneja strings de varios megabytes sin problemas. El bridge copia la memoria una vez en cada direccion, por lo que el tiempo escala linealmente con el tamano.

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.

Ejemplo 16: Dictionary con valores objeto

Cuando el valor del diccionario es un objeto .NET (no un escalar), usa GetObject() para recuperarlo como proxy FoxBridge. Puedes comparar objetos por 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.

Ejemplo 17: DateTime — crear y manipular fechas

System.DateTime permite crear fechas precisas y pasarlas a metodos .NET que las esperan. FoxBridge convierte automaticamente DateTime VFP a DateTime .NET.

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.

Ejemplo 18: Async transparente — Task.Delay

Cuando un metodo .NET devuelve un Task (async), FoxBridge lo espera automaticamente antes de continuar. Desde VFP parece una llamada sincrona normal.

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.

Ejemplo 19: HttpClient — descargar contenido web

HttpClient es una clase async de .NET. FoxBridge la hace sincrona automaticamente. Esto reemplaza WinHTTP, XMLHTTP y cualquier otra dependencia COM que uses hoy.

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.

Ejemplo 20: HttpClient con POST y JSON — llamar una API REST

El caso de uso mas completo: construir un payload JSON con StringBuilder, enviarlo con HttpClient.PostAsync y leer la respuesta. Esto es un cliente REST completo escrito 100% en 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.

Volver a referencia API: Referencia API ->