C# v.12

C# 12 - Nuevas funcionalidades

Nuevas funcionalidades

Constructores primarios

Te permite crear propiedades en una clase desde la línea de construcción de un objeto.

Código convencional:

    public class Student {

        #region Properties

        public int Id {get;set;}
        public string Name {get;set;}
        public string Surname {get;set;}
        public DateTime Birthdate {get;set;}

        #endregion

        #region Builds

        public Student() {}

        public Student(string name, string surname, DateTime birthdate) {
            this.Name = name;
            this.Surname = surname;
            this.Birthdate = birthdate;
        }

        public Student(int id, string name, string surname, DateTime birthdate){
            this.Id = id;
            this.Name = name;
            this.Surname = surname;
            this.Birthdate = birthdate;
        } 

        #endregion

        #region Methods

        public override string ToString() {
            return $"{this.Name} {this.Surname}";
        }

        #endregion

    }

    ... // En otro lugar del programa

    var alumno = new Student();
    var alumno = new Student("Javier", "Cousiño", new DateTime(1986, 1, 5));
    var alumno = new Student(24, "Javier", "Cousiño", new DateTime(1986, 1, 5));

Con los constructores primarios, quedaría tal que así:

    public class Student(int id, string name, string surname, DateTime birthdate)
    {
        public int Id => id;
        public string Name => name;
        public string Surname => surname;
        public DateTime Birthdate => birthdate;
        public override string ToString() => $"{this.Name} {this.Surname}";
    }

También podremos usar este constructor primario desde otros constructores.

    public Student():this(31, "Javier", "Cousiño", new DateTime(1986, 1, 5));

Expresiones de colección

Son una nueva sintaxis más fácil de declarar todos los tipos de colecciones.

Antes:

string[] weekDays = new string[] {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };
List<decimals> temperatures = new () { 31.4, 26.5, 14.9 };

Con las epxresiones de colección, tendríamos el siguiente código:

string[] weekDays =["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
List<decimals> temperatures = [31.4, 26.5, 14.9];

Alias de tipos de datos (usings)

Con esta nueva funcionalidad, vas a poder poner un alias a un tipo de dato.

Ejemplo:

    using DailyValues = List<string, int>;

    DailyValues values = new DailyValues();
    values.Add("Monday", 25);
    values.Add("Thursday", 19);

Valores opcionales en lambdas

Ahora se puede establecer valores opcionales a los argumentos de las funciones lambda:

    var completePhone = (string phone, string prefix = "+34") => $"{prefix} {phone}"; 

Nuevo modificador ref readonly

Ahora se puede usar este nuevo modificador para indicar que el parámetro será por referencia y no se podrá modificar.

    public decimal Calc (int a, ref readonly int b) {
        return a + b;
    }

InlineArray

Este atributo permite definir una secuencia de primitivos. Aplica el tamaño del array a la hora de compilar, no de instanciar el array.

    [InlineArray(16)]
    public struct Students {
        private int _studentsNum;
    }

    Students list = new Students();
    list[0] = 12;
    list[1] = 9;

ExperimentalAttribute

Con este nuevo atributo, podrás indicar que cierta clase es experimental y no está del todo probada. Cuando alguien use esa clase, el compilador le mostrará un aviso indicandolo.

Este nuevo atributo se encuentra dentro del espacio de nombres System.Diagnostics.CodeAnalysis.

Interceptores

Un interceptor es un método que puede, de forma declarativa, sustituir una llamada a un método interceptable por una llamada a sí mismo en tiempo de compilación. Esta sustitución se produce al hacer que el interceptor declare las ubicaciones de origen de las llamadas que intercepta.

Use un interceptor como parte de un generador de origen para modificarlo, en lugar de agregar código a una compilación de origen existente. El generador de origen sustituye las llamadas a un método interceptable con una llamada al método interceptor.

Para usar interceptores, el proyecto de usuario debe especificar la propiedad < InterceptorsPreviewNamespaces >. Se trata de una lista de espacios de nombres que pueden contener interceptores.

<InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>

Referencias