Una sinfonía en C#

Un pequeño aporte a la comunidad de habla hispana.

Tips de Javascript: Lograr que JSON.stringify se comporte a nuestro gusto

Hace ya bastante tiempo que contamos con JSON.parse() y JSON.stringify() para des-serializar y serializar objetos, lo que hace este último es generar una representación JSON de nuestro objeto, al recorrer todas las propiedades del objeto y sus propiedades anidades también, algo así:

image

Esto está muy bien, pero existen ocasiones en las que no queremos esto, por diferentes motivos: no queremos serializar todo, queremos que tenga otra forma, etc. por supuesto que podemos siempre echar mano de un método propio y no usar JSON.stringify, pero si quien consume nuestro código no sabe de la situación es probable que termine haciéndolo, entonces, ¿podemos modificar este comportamiento?

Modificando el comportamiento de JSON.stringify

Sí, existe una forma estándar de decirle al navegador que en lugar de comportarse como lo hace siempre haga exactamente lo que nosotros queremos cuando se usa JSON.stringify, y es tan simple como escribir nuestro propio método toJSON, así algo así;

image

Y magia, vemos que ahora utilizando la función estándar del navegador obtenemos justo lo que queremos.

Nos leemos.

Novedades de C#7: Funciones locales

Ya hemos visto algunas de las novedaes de C#7 en este espacio y es momento de hablar de las funciones locales.

¿Qué son las funciones locales?

En pocas palabras C#7 nos da la posibilidad de declarar una función dentro de otra…si, dentro de otra, con las ventajas que esto aporta:

  • Visibilidad acotada
  • Acceso a las variables del entorno en que se declara
  • No ensuciamos el código con algo muy específico del contexto que necesitamos

Vamos a ver un ejemplo, imaginemos que tenemos una estructura tipo árbol guardada en una base de datos

image

Simple, cada elemento tiene un padre y así se arma el árbol, del lado de C# tenemos:

class Hoja
{
    public string Nombre { get; set; }
    public int Id { get; set; }
    public IList Hijos { get; set; }
    public Hoja Padre { get; set; }
}

Básicamente tiene el nombre, id, el id del padre y el listado de hijos, lo que queremos hacer es armar un árbol poniendo los hijos, lo natural sería hacer algo recursivo.

void BuscarHijos(Hoja hoja, IEnumerable hojas)
{
    foreach (var hijo in hojas.Where(i => i.Padre.Id == hoja.Id))
    {
        hoja.Hijos.Add(hijo);
        BuscarHijos(hijo, hojas);
    }
}

public IEnumerable Generar()
{
    var hojas = Hoja.GetAll();
    var lista = new List();

    foreach (var item in hojas.Where(i => i.Padre == null)) // buscamos los nodos raíz
    {
        lista.Add(item);
        BuscarHijos(item, hojas);
    }

    return lista;
}

Entonces, primero buscamos aquellas hojas que no tiene padres (son las raices) y después iteramos esa colección y buscamos las hojas que tienen como padre al nodo raíz actual, usamos una función recursiva para buscar hijos de hijos, esto debería funcionar.

Usando funciones locales.

El mismo código con funciones locales se pude hacer así:

var lista = new List();

foreach (var item in hojas.Where(i=>i.Padre == null))
{
    lista.Add(item);
    BuscarHijos(item);

    void BuscarHijos(Hoja hoja)
    {
        foreach (var hijo in hojas.Where(i => i.Padre.Id == hoja.Id))
        {
            hoja.Hijos.Add(hijo);
            BuscarHijos(hijo);
        }
    };
}

Como vemos declaramos la función BuscarHijos no solo dentro del método sino dentro del bucle y acotamos bien su impacto, además tenemos visibilidad de la lista de hojas y de la misma función BuscarHijo, super cool

Hay más detalles sobre las funciones locales en este link, y la propuesta original de la funcionalidad acá.

Nos leemos.

Novedades de C#7: Ref Returns y Ref locals

Ya hablamos de algunas de las novedaes de C#7 como literales binarios, variables de salida y pattern matching, seguimos con las novedades del C# en este caso vamos a ver ref Returns y ref locals.

Una historia interesante

Si hay una cosa que me gusta mucho de estas features es que nacieron como comunidad, una propuesta en Github que se discute, se analiza, se propone y termina llegando a C#, algo impensado 5 años atrás, esto es muy interesante pensando en el futuro y la evolución del lenguaje.

Ahora sí, qué son ref returns y ref locals?

Desde siempre en C# podemos pasar parámetros por referencia así:

int val = 1;
Method(ref val);
Console.WriteLine(val);

Entonces el método “Method” modifica el valor de la variable val que le pasamos, es decir, utiliza el mismo espacio de memoria.

ok, sin embargo si el método retornase un valor este sería una copia, ahí entran los ref return

static ref Persona HacerAlgo(ref Persona p)
{
    return ref p;
}

Más allá de que el método no hace nada lo interesante es que nos retorna el mismo objeto (no una copia) que le pasamos, entonces dentro del método modificamos el mismo objeto que se pasó como referencia.

Para qué es útil esto?

En el caso de manipular variables muy grandes usar siempre la misma referencia puede tener un impacto positivo enorme ya que no es necesario hacer copias y reservar más memoria.

ref locals

Otra feature asociada a este es la posibilidad de declarar variables ref dentro del método para utilizarla como valores de retono ref buscardo nuevamente mejor performance.

ref Persona local = ref p;

Nos leemos!

Xamarin Dev Days Buenos Aires 2016

El viernes 2 de Diciembre he tenído el honor de participar en #XamarinDevDays en Buenos Aires tanto como organizador como speaker, el evento tuvo lugar en las oficinas de Microsoft de Argentina en Buenos Aires desde las 9hs hasta las 16hs.

Gracias!

Lo primero que quiero decir es gracias a quienes me dieron la oportunidad de organizar este evento Jayme, Diana y a los que ayudaron desde Microsoft Argentina Soledad y Carolina, sin ellas hubiera sido imposible; todo el tiempo que duró la organización así como durante el evento cada una de ellas dio una gran mano.

A todos los asistentes por tomarse todo un día para compartir con nosotros.

También quiero agradecer a los speakers, además de mí estuvieron Alex Pestchanker y Sebastián Pérez, ambos dieron excelentes charlas.

El evento

El evento contó con tres charlas y un Hand on lab después del almuerzo en el cual los asistentes desarrolaban su primera aplicación con Xamarin Forms conectada a Azure y todo salió más que bien.

Lo más importante de todo fue la convocatoria, éramos más de 40 personas que llegaron bien temprano y de ellos más de 30 estuvieron hasta el final y simpre mostrando un gran interés en el tema y muy buena predisposición.

Dejo algunas fotos del evento.

XamarinDevDays-5XamarinDevDays-7XamarinDevDays-18XamarinDevDays-8XamarinDevDays-15XamarinDevDays-34

Quiero agradecer especialmente a Meri y Ale por ayudarnos con la promoción, para los que no vieron hicimos un par de videos:

Nos leemos.

C# 6: ¿Qué son los operadores “explicit” e “implicit”?

En ocasiones nos encontramos con la necesidad de convertir entre dos tipos que no son directamente equivalentes, por ejemplo un tipo Usuario a un int, pero tal vez sea un caso válido para nosotros (sin llegar a tanto como en el ejemplo), imaginemos que tenemos un tipo Moneda, así:

public class Moneda
{
    public decimal Valor { get; set; }
    public string Simbolo { get; set; }

}

Y queremos hacer una instancia de, por ejemplo, una moneda del tipo “$”, bueno, no nos queda mucho más que hacer esto:

var a = new Moneda();
a.Simbolo = "$";

Lo cual está bien (incluso podríamos hacerlo en una línea) pero bueno, en este caso no estamos directamente convitiendo el “$” en una instancia de moneda con ese símbolo sino que estamos creando una moneda y después cambiando ese valor.

Conviertiendo entre tipos no compatibles

Bien, existe una forma de hacerlo en C#, en realidad dos formas, explícita o implícita. y son operadores, vamos a ver un ejemplo:

public class Moneda
{
    public decimal Valor { get; set; }
    public string Simbolo { get; set; }

    //permite convertir implícitamente, es decir Moneda a = "$"
    public static implicit operator Moneda(string s)
    {
        return new Moneda { Simbolo = s };
    }

    //permite convertir explícitamente, es decir Moneda a = (Moneda) 1;
    public static explicit operator Moneda(decimal i)
    {
        return new Moneda { Valor = i };
    }
}

Y como indica el código, el operador implicit permite hacer una conversión directa, en este caso igualar un tipo objeto Moneda contra un string, el explícito nos pide indicar explícitamente la conversión agregando el tipo entre paréntesis. La implementación no es una que la construcción de un objeto Moneda.

var a = new Moneda();

//conversión implícita
a = "$";

//conversión explícita
a = (Moneda) 1;

Cool, si miramos el IL vemos que lo que hace el compilador es hacer llamadas a los métodos de conversión cuando se intenta hacer la asignación

IL_0000: nop
IL_0001: newobj instance void ConsoleApplication1.Moneda::.ctor()
IL_0006: stloc.0
IL_0007: ldstr "$"
IL_000c: call class ConsoleApplication1.Moneda ConsoleApplication1.Moneda::op_Implicit(string)
IL_0011: stloc.0
IL_0012: ldsfld valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::One
IL_0017: call class ConsoleApplication1.Moneda ConsoleApplication1.Moneda::op_Explicit(valuetype [mscorlib]System.Decimal)
IL_001c: stloc.0
IL_001d: ret

Como vemos en las líneas 000c y 0017 se llama a los método op_Implicit y op_Explicit que hacen las conversiones.

Nos leemos.