Felices fiestas!

Queridos amigos, celebréis lo que celebréis, os deseo a todos unas felices fiestas!. Normalmente, añadiría «junto a vuestros seres queridos», pero esta vez solo añadiré, cuidaos mucho, al igual que a todos los que os rodean.

Felices fiestas!

Para el 2022!

Para el próximo año solo pido mirar hacia delante con alegría y optimismo además de salud. Son los ingredientes básicos para tener un buen año!.

Felices fiestas!

[SevillaDotNet] Mesa redonda de .NET 6

Tras la .NET Conf 2021 y el lanzamiento de .NET 6 tenemos una enorme cantidad de novedades: C# 10, .NET 6, Visual Studio 2022, etc.

¿Algo mejor que montar una mesa redonda donde invitar a diferentes desarrolladores y repasar las novedades principales?

La fecha

Será el próximo Jueves, 25 de Noviembre de 18:30h a 20:00h (GMT+1).

¿Te apuntas?

Puedes seguir el evento en YouTube:

Más información

Más novedades de .NET 6, PriorityQueue

Diría que es hasta sorprendente tras ver durante años diferentes implementaciones de PriorityQueue incluidas algunas usadas interamente en Frameworks de Microsoft, que nunca ha existido algo público directamente expuesto en .NET. Esto ha sido así hasta la llegada de .NET 6. En este artículo vamos a conocer las posibilidades de PriorityQueue.

Queue

Para explicar las novedades introducidas vamos a crear una pequeña clase que nos permita trabajar con personas.

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Vamos a comenzar trabajando con Queue. Se trata de una estructura de datos genérica en la que los elementos se recuperan en el orden en que se añaden.

var persons = new Queue();

persons.Enqueue(new Person() { Name = "Javier" });
persons.Enqueue(new Person() { Name = "David" });
persons.Enqueue(new Person() { Name = "Pedro" });
persons.Enqueue(new Person() { Name = "Jesus" });

Vamos a utilizar el método TryDequeue que quita el elemento situado al principio y lo copia en el parámetro de salida.

while (persons.TryDequeue(out var person))
{
    Console.WriteLine($"{person.Name}");
}

La salida será algo como:

  • Javier
  • David
  • Pedro
  • Jesus

Justo lo que esperábamos y ya conocíamos, elementos ordenados obteniendo en cada momento el primero del principio de la colección.

Ahora imagina que quieres utilizar otro criterio para priorizar el orden en el que aparecen los elementos, independientemente del orden en que se pongan en cola.

Digamos que en nuestro ejemplo, cada persona tiene una edad y queremos ordenar usando ese criterio.

PriorityQueue

Podemos usar la nueva clase PriorityQueue con ese objetivo, usar otro criterio para priorizar.

Añadimos varias personas a un PriorityQueue:

var prioritizedAgents = new PriorityQueue();

prioritizedAgents.Enqueue(new Person() { Name = "Javier" }, 36);
prioritizedAgents.Enqueue(new Person() { Name = "David" }, 45);
prioritizedAgents.Enqueue(new Person() { Name = "Pedro" }, 41); 
prioritizedAgents.Enqueue(new Person() { Name = "Jesus" }, 33);

Como podemos ver en el ejemplo anterior, se especifica el tipo a añadir en la cola y un segundo tipo, que se usarará para la priorización.

En nuestro caso, tenemos una cola de personas y la prioridad es la edad donde se usa un int.

while (prioritizedAgents.TryDequeue(out var person, out var age))
{
    Console.WriteLine($"{person.Name}, age {age}");
}

¿Cuál es el resultado?

  • Jesus, age 33
  • Javier, age 36
  • Pedro, age 41
  • David, age 45

Las personas ordenadas por edad. Hay que tener en cuenta el orden relativo a como se añadieron a la cola. Al priorizar,un valor más bajo otorga una prioridad más alta.

Por supuesto, el tipo utilizado para definir la prioridad no tiene que ser un número; puede ser cualquier cosa que implemente IComparer.

Estamos ante una novedad excelente para problemas en los que las estructuras de datos se procesan según el orden y además otro parámetro que otorga prioridad.

Más información

[C# 10] Const Interpolated Strings

Continuamos hablando de novedades de C# 10. En esta ocasión hablaremos de cadenas interpoladas constantes, nueva funcionalidad que llega para hacer que nuestro código sea más legible y más conciso.

Concatenar cadenas constantes hasta ahora

Cuando usamos cadenas constantes en C# 9.0 y versiones anteriores, solo podíamos concatenarlas usando el operador +:

const string Scheme = "https"; 
const string Home = "home";

const string Environment = Scheme + "://localhost:5002";const string HomeUri = Environment + "/" + Home;

Nuevas posibilidades

Con la llegada de C# 10, ahora podemos usar el operador de cadena interpolada $ para combinar cadenas constantes:

const string Scheme = "https"; 
const string Home = "home";

const string Environment = $"{Scheme}://localhost:5002";
const string HomeUri = $"{Environment}/{Home}";

NOTA: Es importante tener en cuenta acerca de esta función es que solo funciona si todas las cadenas utilizadas en la cadena interpolada están marcadas const.

¿Qué te parece este añadido?. Recuerda que puedes usar los comentarios de la entrada para dejar tu feedback.

Más información

[.NET 6] DateOnly y TimeOnly

Estamos muy cerca del lanzamiento de .NET, el próximo 9 de Noviembre. Así que, es un momento ideal para comenzar una nueva seria de artículos donde hablar de novedades. En este artículo, vamos a hablar de DateOnly y TimeOnly.

Clock

Trabajando con fechas

Hasta ahora, para trabajar con fechas usábamos la clase DateTime.

var date = new DateTime(1985, 7, 23);
var onlyDate = DateTime.Now.Date;

Con bastantes constructores y métodos, podíamos crear fechas de diferentes formas pero siempre trabajando con el tipo DateTime que incluye el tiempo aunque no lo necesitásemos.

De igual forma, no tenemos una forma de representar una hora del día sin incluir información de la fecha. Tenemos a nuestra disposición la clase TimesSpan que pueden representar tiempo transcurrido (2 horas, 20 minutos y 5 segundos) pero para representar una hora del día necesitamos DateTime.

Nuevas posibilidades

Con la llegada de .NET 6 se introducen nuevas estructuras, DateOnly y TimeOnly que permiten representar fechas sin una hora del día y una hora del día sin fecha respectivamente.

// DateOnly is a new struct in .NET 6 that represents just a date.
DateOnly july23th = new DateOnly(1985, 7, 23);

// TimeOnly is a new type in .NET 6. Stores a time without a date.
TimeOnly tenThirtyPM = new TimeOnly(22, 30); // 22:30, or 10:30 PM

DateOnly

La nueva struct cuenta con los mismo métodos que ya existían en DateTime para modificar la fecha: AddDays, AddMonths y AddYears.

// Like with DateTime, we can add days, months, and years.
var dateOnlyFromDateTime = dateOnlyFromDateTime.AddYears(1).AddMonths(2).AddDays(15); // Apr 29th, 2001

DateOnly almacena los valores como un entero, donde el valor 0 corresponde al 0 de Enero, 0001. De esta forma, es posible convertir un entero a un DateOnly usando el método FromDayNumber.

DateOnly dateOnlyInteger = new(1985, 7, 23); // Jul 23th 1985
int dayNumber = dateOnlyInteger.DayNumber;
DateOnly resultFromDayNumber = DateOnly.FromDayNumber(dayNumber);

También es posible creat una instancia de DateOnly desde una cadena usando el método TryParse.

// We can parse like uusing DateTime with the TryParse method.
DateOnly.TryParse("01/21/2020", out DateOnly result);

TimeOnly

La struct TimeOnly almacena la información usando un long que representa el número de ticks desde medianoche.

TimeOnly elevenTen = new TimeOnly(11, 10);
long ticks = elevenTen.Ticks;
TimeOnly timeOnlyTicks = new TimeOnly(ticks);

Podemos crear una instancia TimeOnly desde un DateTime usando el método FromDateTime.

DateTime dateTime = new DateTime(2020, 12, 12, 8, 00, 00);
TimeOnly timeOnlyFromDateTime = TimeOnly.FromDateTime(dateTime);

Podemos realizar operaciones matemáticas entre instancias de TimeOnly que nos devolverá como resultado un TimeSpan.

var afternoon = new TimeOnly(17, 00); // 5:00 PM
var morning = new TimeOnly(8, 00); // 8:00 AN
TimeSpan difference = afternoon - morning; // 9 hours

En general, nuevas structs que en mi opinión se integrarán facilmente con el resto de posibilidades de .NET y sobretodo será útil en tareas donde haya operaciones de serialización o bases de datos.

¿Qué te parecen estas novedades?. Recuerda, puedes usar los comentarios de la entrada para dejar tu opinión.

Más Información

.NET Blog: Date, Time, and Time Zone Enhancements in .NET 6

[C# 10] File Scoped Namespaces

Seguimos repasando novedades de C# 10. En esta ocasión, vamos a centrarnos en File Scoped Namespaces.

Declaración normal de namespaces (hasta ahora)

Imagina que creamos una clase Person.cs con el siguiente contenido.

using System;

namespace FileScopedNamespaceSample
{
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

La clase Person.cs se encuentra en el namespace FileScopedNamespaceSample. Cuando se observa el fragmento de código anterior, se puede ver que la declaración del espacio de nombres normal necesita un par de corchetes.

¿Y si pudiesemos simplificar esto?.

File Scoped Namespaces

A continuación, veremos un fragmento de código que muestra una declaración de espacio de nombres de ámbito de archivo (File Scoped Namespace) que es posible con C# 10.

using System;

namespace FileScopedNamespaceSample;
    
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Como puedes ver, después del espacio de nombres se agrega un punto y coma, y no corchetes como con una declaración de espacio de nombres clásica. Este espacio de nombres de ámbito de archivo significa que todos los tipos de este archivo, como clases e interfaces, están en el espacio de nombres FileScopedNamespaceSample.

Es posible igualmente colocar la declaración del espacio de nombres en la parte superior del archivo, encima de la directivas using.

namespace FileScopedNamespaceSample;
   
using System;

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Pero no es posible colocar la declaración del namespace al final del archivo.

También es importante destacar que solo podemos declarar un espacio de nombres de ámbito de archivo por archivo. Por lo general, la mayoría de las clases C# tienen solo un espacio de nombres, por lo que no hay problema.

Pero, ¿qué sucede si deseas declarar más de un espacio de nombres en un solo archivo?.

Esto no es algo posible con espacios de nombres de ámbito de archivo. Si intentas agregar otro espacio de nombres con ámbito de archivo en el mismo archivo, obtendrás un error en el IDE.

Los espacios de nombres de ámbito de archivo son una nueva posibilidad pequeña, pero interesante y útiles en diferentes casos.

¿Qué te parece esta nueva funcionalidad?. Recuerda, puedes usar los comentarios de la entrada para dejar tu feedback.

Más información

[C# 10] Global Usings

Una de las novedades más sonadas quizás por ser un cambio del que estoy seguro tendrá desarrolladores a favor y otros en contra. En este artículo, vamos a hablar de la llegada de Global Usings.

Declarar usings hasta ahora

En la parte superior de todas las clases C# hay una colección de instrucciones using que especifican los espacios de nombres que la clase necesita para compilar:

using System;

namespace GlobalUsingsSample
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Global Usings!");
        }
    }
}

Cuando en el mismo proyecto tenemos diferentes clases haciendo uso de las mismas APIs, aparecen duplicadas instrucciones using.

Es cierto que Visual Studio puede colapsar los usings, pero, ¿y si se pueden gestionar de otra forma?.

Global Usings

C # 10 permite hacer uso de la palabra global para poder identificar namespaces que deberían aplicarse a toda nuestra aplicación:

global using System;

// The previous using statements will be included in every class in this project.

Estas declaraciones pueden colocarse en un archivo en cualquier lugar del proyecto, y el compilador de C# sabrá que tiene que aplicar estos namespaces a nivel de aplicación.

De esta forma:

namespace GlobalUsingsSample
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Global Usings!");
        }
    }
}

No hay namespaces a nivel de la clase!. Pero…¿y si añades un namespace a nivel de clase que ya se encuentra a nivel global?. Visual Studio avisará de este caso con un warning.

Más información

Calendario común de comunidades .NET de España

¿Y si en un lugar centralizado y común pudieramos ver de un vistazo todos los eventos de tecnologías .NET que hay en España?. Esta es la idea principal de la que quiero hablaros hoy en este artículo.

El origen

Hablar con otros de tecnología, proyectos e ideas es algo de lo que personalmente disfruto mucho. Poder ayudar a otros, crecer entre todos es genial. Y en ocasiones, nacen buenas ideas. En una de estas conversaciones con Marcelo Villacorta en la comunidad .NET de Sevilla salía esta idea "estaría genial poder sincronizarnos entre todas las comunidades, saber de forma fácil que eventos existen, etc".

Idea

Esta idea fue planteada en una reunión periódica que se tiene tiene entre toda la comunidad (bueno, con representates de cada una de las comunidades .NET de España) recibiendo muy buena aceptación!.

La implementación

Tras aterrizar algunas ideas, me complace poder compartir el calendario común de las comunidades .NET de España.

Se trata de una página web donde se sincronizan de forma automática cada día los eventos de cada una de las comunidades .NET de España. La sincronización obtiene cada día los nuevos eventos (o los eventos existentes si se han editado) utilizando las APIs de Meetup y eventbrite.

Con posibilidad de poder hacer búsquedas, exportar los eventos a tu propio calendario así como poder visualizar la información en diferentes modos como vista semanal, mensual, en un listado, etc., la página tiene como objetivos:

  • Facilitar la visualización de todos los eventos de la comunidad de forma sencilla de modo que ayude tanto a evitar eventos en el mismo día y hora (siempre y cuando sea posible) así como ayudar a dar visibilidad de eventos entre todos.
  • Tener una herramienta más para obtener información de forma sencilla. ¿Cuál es el mes con más eventos?, ¿cuantos eventos se celebraron en todo un año?, etc.
  • En definitiva, ayudar a actuar más como UNA gran comunidad, un bloque común aunque haya distancia separando algunos grupos de usuario de otros.

Calendario .NET

Necesitamos tu ayuda!

El requisito para cada comunidad es sencillo, sólo necesitamos registrar su comunidad (página web a la misma) en el calendario para que comience la sincronización!. Si tu comunidad no esta entre el listado de comunidades actualmente incluidas, puedes añadirla enviando una Pull Request en este repositorio.

Se trata de un proyecto por y para la comunidad así que cada paso importante deberíamos darlo entre todos juntos. Uno de estos primeros pasos es… el nombre. Tener un nombre, una marca reconocible es importante. Al fin y al cabo es lo que todos usaremos para navegar a su dominio, usaremos este nombre al referirnos al calendario, etc. Para este tipo de decisiones usaremos Issues de GitHub. Puedes encontrar la Issue donde poder aportar tu idea para el nombre aquí.

Más información

Monkey Conf 2021

Otro año más, y otra edición de la Monkey Conf nueva. Este ao es ya la cuarta edición. Hablamos del mayor evento centrado en desarrollo multiplataforma con C# realizado en España. Una fecha especial para reunir a la comunidad, disfrutar de sesiones técnicas, networking y compartir momentos entre todos.

Monkey Conf 2021

Este año, al igual que el año pasado, debido a la situación con el Covid-19, el formato será online.

La fecha

Este año el evento tendrá lugar entre semana el próximo Miércoles 01 de Diciembre.

De igual forma, al ser el evento online y aunque contar con entradas nos ayudaría a conocer de forma aproximada el interés en el evento, este año no tendremos entradas.

Call 4 Papers

¿Has desarrollado una aplicación con Xamarin?, ¿quieres hablar de .NET MAUI?, ¿Apps en Linux con Avalonia?. El Call 4 Papers del evento ya se encuentra disponible. Este año al ser un evento online nos abre la posibilidad de tener speakers de cualquier lugar del mundo!.

Sponsors

En años anteriores, gracias a sponsors cubríamos costes básicos del evento como goodies (pegatinas, camisetas, etc.), el almuerzo, etc. Este año el evento es online, y seguimos buscando Sponsors.

¿Por qué?.

Creemos que estamos viviendo momentos complicados para todos, y pensamos que gracias a sponsors podríamos sortear y regalar licencias de productos relacionados con el desarrollo, etc. Buscamos tener un pequeño gesto que ayude a alegrar el día a asistentes y esto sería posible gracias a la ayuda de Sponsors.

Si estas interesado en patrocinar el evento, puedes encontrar más información en la página web del evento.

Más información

Utilizando el Windows Subsystem para Android para desarrollar

Si has desarrollado con .NET y Xamarin en los últimos años recordarás la evolución al trabajar con emuladores Android. El paso de los emuladores por defecto a Intel HAXM fue un gran paso adelante en el rendimiento general; luego pasamos a tener más opciones como Xamarin Android Player para finalmente llegar al soporte de Hyper-V lo que facilitó otro salto en rendimiento y tiempo de arranque.

¿Y si estamos ante el siguiente salto?. En este artículo, vamos a conocer el Windows Subsystem para Android así como lo necesario para utilizarlo para desarrollar y depurar aplicaciones Android.

Windows 11

Entre las novedades de Windows 11 nos llega un subsistema de Android.

Windows 11

El objetivo principal es el permitir ejecutar aplicaciones Android en Windows. No existe un launcher Android o similar, Windows es directamente quien se encarga de lanzar las Apps.

Amazon App Store

Como usuarios, aunque no es la única vía, se pueden obtener aplicaciones Android desde la Store utilizando la Amazon App Store.

Instalar el subsistema de Android en Windows 11

Lo primero que debemos hacer es tener una build de Windows Insiders Beta (al momento de escribir este artículo) que coincida con Windows 11 Build 22000.xxx.

Windows 11 Build 22000.xxx

Tras tener esta versión de Windows es hora de instalar el Windows Subsystem for Android que tambien viene con la Amazon App Store.

Este paso es sencillo, solo hay que entrar en la Store, instalar y reiniciar.

Instalar WSA

Hora de desarrollar!

Dentro del WSA App encontrarás bastantes opciones.

Opciones WSA

Necesitamos cambiar varias opciones:

  • Habilitar el modo Continuous para que el subsistema siempre este listo para ser usado.
  • Activar el modo de desarrollador.

NOTA: Al activar el modo de desarrollador veremos las instrucciones necesarias para conectar por adb.

Con el subsistema Windows para Android en ejecución podemos usar 127.0.0.1:58526 para conectar y hacer debugging.

adb connect 127.0.0.1:58526

NOTA: Lo visto anterior es la forma por defecto para conectar con WSA pero puedes encontrar más opciones en la documentación oficial.

Una vez conectado vía adb, sencillamente aparecerá la opción de WSA en Visual Studio.

Visual Studio

Más información