La .NET CONF 2024 acaba de terminar. Descubre las NOVEDADES de .NET 9 junto a los CAMBIOS que trae C# 13.
Puedes ver el contenido de este vídeo junto con su curso en el modo vídeo (similar a Udemy) si pulsas aquí.

Novedades C# 11

en este post vamos a ver la lista de novedades que salen con C# 11 la semana que viene. Si alguno cambia, actualizaré el post.

Ya sabes que estas características vienen de la mano de NET 7, el cual veremos en profundidad en otro post.

 

 

1 - Palabra clave required 

Vamos a empezar con uno de los cambios que más me afectan a muy si bien es cierto que parece un cambio pequeño no lo es, porque debido a este cambio, podemos tener records con nullable activado como objetos dentro del patrón Options. Esto es debido a que hasta ahora, si teníamos un record como objeto para el patrón, debíamos deshabilitar nullable en ese fichero.

 

Esto no pasa más, ya que la keyword required nos va a cubrir esa necesidad de no tener que desactivar nullable

public record EjemploRequired
{
    public required string ApiKey { get; init; }
}

Este ejemplo sin la keyword required en c# 10 nos devolvería un warning o bueno un error si tenemos configurado los warnings de errores. 

Personalmente, pienso que init debería implicar required. Pero bueno, no es el fin del mundo tampoco añadir una palabra más. 

  • Posiblemente cree un vídeo específico para esta funcionalidad.

 

 

2 - Patrones en listas

En las últimas versiones del lenguaje hemos visto que han añadido varias mejoras en el pattern matching ahora le toca al pattern matching de las listas, tenemos dos cambios principales

 

ahora podemos hacer array is [1,2,3] y nos devuelve verdadero o falso.

int[] ejemploArray = new int[] { 1, 2, 3, 4, 5, 6, 7 };

bool result = ejemploArray is [1, 2, 3];

 

Como nota adicional, también podemos utilizar .. para indicar rangos lo cual pues esta bien, muchos otros lenguajes tienen la misma funcionalidad así que puede ayudar a desarrolladores de otros lenguajes a pasarse a C#. 

var resultado = ejemploArray switch
{
    [1, .., 7] => 1,
    [1, 2, 3] => 1,
    [2, 3] => 2,
    _ => throw new NotImplementedException(),
};

 

Aunque imagino que la funcionalidad no está completada al 100% ya que por ahora no permite por ejemplo arrays multidimensionales.

 

 

3 - Modificador de acceso file

Con la llegada de c# 11 el equipo de Microsoft va a incluir un nuevo modificador de acceso. En este caso, el modificador de acceso file, el cual da visibilidad al fichero en el que es declarado.

 

Inicialmente se creó para permitir a la gente que utiliza source generator para prevenir colisión de nombres, pero como persona que crea librerías constantemente, también lo veo de mucha utilidad. 

public class CualquerCasoDeuso
{
    public void Execute()
    {
        FileScope fileScope = new();
        fileScope.Execute();
    }
}

file class FileScope
{

    public void Execute()
    {
        Console.WriteLine("este metodo solo se puede llamar desde el mismo fichero");
    }
}

Simplemente igual que otros modificadores de acceso, la única diferencia es que se llama file y no se puede utilizar fuera del mismo fichero.

 

 

4 - Cambios en el tipo string en C# 11

En esta versión tenemos varios cambios relacionados o que tocan string, o texto en general, yo los meto todos en el mismo bloque.

 

4.1 - Strings literales puras

Hasta ahora en C#, si queremos poner strings tal y como están en el código no podemos ponerlo tal cual, en el siguiente ejemplo todos los espacios de la derecha e izquierda se quitan.

 

No solo eso, sino que no podemos tener variables, bueno si podemos pero es un poco jaleo. 

 

Con la llegada de las sting literales puras, este problema se soluciona, podemos especificar el carácter $ para indicar que queremos poner variables, además, podemos indicar más de uno para indicar que quieres poner más de un caracter { en tu código para indicar que quieres variables.

string stringLiteral = """
            esto es 
            un ejemplo de string literal:
                    con diferentes niveles de interpolacion
        """;

string valor1 = "test";
string stringLiteralPura = $$$"""
            esto es 
        un ejemplo de string literal pura:
        donde podemos poner variables: {{{valor1}}}
        """;

Si pusiéramos otro símbolo $, tendríamos que poner otra combinación de { } agrupado la variable

 

4.2 - String literales en UTF-8

Si indicas u8 al final de una frase, puedes almacenar esa frase cómo literal en formato de byte, ya sea en un span<byte> o en un array byte[].

byte[] resultado = "Esto es una frase de ejemplo"u8.ToArray();

 

Un par de cosas a tener en cuenta, este tipo de string son literales en tiempo de ejecución no de compilación, lo que tiene dos implicaciones en c#

  1. No se puede utilizar junto con variables, osea no puedes hacer String.Format en ellas
  2. No se pueden utilizar como valor por defecto.

 

4.3 - Cambios en string interpolation

A partir de ahora cualquier cosa que pongamos dentro de { y } será evaluado como C# lo que permite anadir saltos de linea y si no me equivoco el pattern matching de las expresiones swich que fue introducida en c#9.

int variable = 1;
string example = $"El valor de ejemplo es: {variable switch
{
    > 1 => "el valor es 1",
    _ => "valor no registrado",
}}";

 

 

5 - ref fields dentro de ref structs

Ahora podemos crear un miembro con la palabra clave ref dentro de un ref struct:

public ref struct EjemploRef
{

    public ref int valor;
    public int Getvalor()
    {
        if (System.Runtime.CompilerServices.Unsafe.IsNullRef(ref valor))
        {
            throw new InvalidOperationException("El valor no ha sido inizializdo");
        }

        return valor;
    }
}

Yo personalmente no he tenido nunca que hacer nada así, y tampoco se me ocurre un caso de uso.

Por cierto, antes de salir de los structs, desde ahora, los structs inicializan a su valor por defecto como parte de la ejecución de su constructor, así se aseguran que todo se inicializa por el compilador. 

internal struct StructValorPorDefecto
{
    private int Valor { get; set; } //se asigna 0 por defecto
    public StructValorPorDefecto()
    {
    }
}

 

 

6 - Soporte para Generic Math

En c# 10 Microsoft introdujo Generic Math, pero la comunidad notaba que faltaban varias características que quieren tener disponibles.

 

Bueno Microsoft escuchó y ha implementado una serie de cambios para que los desarrolladores puedan aprovechar los operadores y las apis estáticas convirtiéndolas en static virtual y utilizando generics

Personalmente no creo que en el 99.9% de los casos este cambio no significa nada en su día a día, pero para ese 0.1 restante es un cambio brutal. Yo estoy en el 99.9%.

 

 

7 - Atributos genéricos en c#

Un cambio que yo creo voy a utilizar bastante también es el de los atributos genéricos, básicamente ahora vamos a poder pasar el generic T a nuestro atributo;

 

y esto antes no se podía hacer, si que es verdad que podíamos pasar el tipo como parámetro del constructor pero era una guarrada de narices, ahora es mucho más elegante y fácil de comprender:

public class GenericAttribute<T> : Attribute
{

}

internal class AtributosGenericos
{
    [GenericAttribute<string>]
    public void Example() { }
}

Código, una cosa a tener en cuenta es que no puedes pasar el atributo Genérico de la clase a la que llama, osea cuando específicas el atributo, debes especificar el tipo que va en el atributo.

 

Tampoco podemos pasar el tipo dynamic, tipos nullables, o tuplas. los tipos Object y ValueTuple<T, U> si están permitidos.

internal class AtributosGenericosEj2<T>
{
    //esto no compila
    [GenericAttribute<T>]
    public void Example() { }
}

 

 

8 - Comprobar parametros nulos

Como algunos sabreis ya vimos en este blog las formas de comprobar valores nulos dentro de C#, en este post mencione el parameter null checking, que consiste en añadir el caracter “bang” ! (exclamación) después del nombre, bueno dos !!.

 

Pese a que fue incluido en una de las versiones preview al final el equipo de microsoft decidió quitarlo de esta release debido a la respuesta de la comunidad, en el que básicamente decía que no le gustaba la idea. 

 

Y en mi opinión, con razón, esto es un ejemplo de parameter null checking:

//Ejemplo(no compila)
public void Example(int valorNoNulo!!)
{

}

 

Y pienso que es correcto que no lo incluyan a mi personalmente no me gusta, si por ejemplo el bangger estuviera en el tipo de dato, quizá podría entenderlo, pero en la variable no tiene sentido, veremos lo que muestran en el futuro, porque la idea es buena de verdad y espero que piensen algo que contente a la mayoría.


Uso del bloqueador de anuncios adblock

Hola!

Primero de todo bienvenido a la web de NetMentor donde podrás aprender programación en C# y .NET desde un nivel de principiante hasta más avanzado.


Yo entiendo que utilices un bloqueador de anuncios como AdBlock, Ublock o el propio navegador Brave. Pero te tengo que pedir por favor que desactives el bloqueador para esta web.


Intento personalmente no poner mucha publicidad, la justa para pagar el servidor y por supuesto que no sea intrusiva; Si pese a ello piensas que es intrusiva siempre me puedes escribir por privado o por Twitter a @NetMentorTW.


Si ya lo has desactivado, por favor recarga la página.


Un saludo y muchas gracias por tu colaboración

© copyright 2024 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café