Tipi costruiti non gestiti in C#

Tipi costruiti non gestiti in C#

Tipi costruiti non gestiti in C# 8 con esempi

In questo articolo parlerò dei Tipi costruiti non gestiti in C# 8 con esempi. Si prega di leggere il nostro articolo precedente in cui abbiamo discusso di Operatore di assegnazione a coalescenza nullo in C# 8 con esempi. In C# 7.3 e versioni precedenti, un tipo costruito (un tipo che include almeno un tipo di argomento) non può essere un tipo non gestito. A partire da C# 8.0, un tipo di valore costruito non è gestito se contiene solo campi di tipi non gestiti.

Che cos'è il tipo non gestito in C#?

Un tipo viene chiamato costruito se è generico e il parametro di tipo è già definito. Ad esempio, List è un tipo costruito mentre List non lo è.

Un tipo viene chiamato non gestito quando può essere utilizzato in un contesto non sicuro. Questo è vero per molti tipi di base incorporati. Un tipo è un tipo non gestito se è uno dei seguenti tipi:

  1. sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal o bool
  2. Qualsiasi tipo di enum
  3. Qualsiasi tipo di puntatore
  4. Qualsiasi tipo di struttura definito dall'utente che contiene solo campi di tipi non gestiti.
Che cos'è il tipo costruito in C#?

Un tipo è chiamato tipo costruito se è generico e il parametro di tipo è già definito, come List, List, ecc. In C# 7.3 e precedenti, un type (un tipo che include almeno un tipo di argomento) non può essere un tipo non gestito. A partire da C# 8.0, un tipo di valore costruito non è gestito se contiene solo campi di tipi non gestiti.

A partire da C# 7.3, è possibile utilizzare il vincolo non gestito per specificare che un parametro di tipo è un tipo non gestito non annullabile e non puntatore. A partire da C# 8,0, anche un tipo struct costruito che contiene solo campi di tipi non gestiti non è gestito, come mostra l'esempio seguente:

using System;
namespace Csharp8Features
{
    public struct Coords<T>
    {
        public T X;
        public T Y;
    }

    public class UnmanagedTypes
    {
        public static void Main()
        {
            DisplaySize<Coords<int>>();
            DisplaySize<Coords<double>>();
        }

        private unsafe static void DisplaySize<T>() where T : unmanaged
        {
            Console.WriteLine($"{typeof(T)} is unmanaged and its size is {sizeof(T)} bytes");
        }
    }
}
Risultato:

Una struttura generica può essere l'origine di tipi costruiti sia gestiti che non gestiti. L'esempio precedente definisce una struttura generica Coords e presenta gli esempi di tipi costruiti non gestiti. Un esempio di tipo gestito è Coords. È gestito perché ha i campi del tipo di oggetto, che è gestito. Se desideri che tutti i tipi costruiti siano tipi non gestiti, utilizza il vincolo non gestito nella definizione di una struttura generica come mostrato di seguito.

public struct Coords<T> where T : unmanaged
{
       public T X;
       public T Y;
}
Tipi costruiti non gestiti:

Consideriamo il seguente esempio di un tipo costruito non gestito che non era possibile dichiarare prima di C# 8.0.

public struct Foo<T>
{
    public T var1;
    public T var2;
    public T var3;
}

L'esempio sopra definisce il tipo generico Foo. Il tipo Foo è un tipo non gestito in C# 8,0 e per qualsiasi tipo non gestito è possibile creare un puntatore a una variabile di questo tipo o allocare un blocco di memoria nello stack per istanze di questo tipo come illustrato di seguito.

Span<Foo<int>> bars = stackalloc[]
{
    new Foo<int> { var1 = 10, var2 = 20, var3 = 30 },
    new Foo<int> { var1 = 11, var2 = 21, var3 = 31 },
    new Foo<int> { var1 = 21, var2 = 22, var3 = 32 },
};
Codice di esempio completo:
using System;
namespace Csharp8Features
{
    public struct Foo<T>
    {
        public T var1;
        public T var2;
        public T var3;
    }

    public class UnmanagedTypes
    {
        public static void Main()
        {
            // Block of memory
            Span<Foo<int>> bars = stackalloc[]
            {
                new Foo<int> { var1 = 10, var2 = 20, var3 = 30 },
                new Foo<int> { var1 = 11, var2 = 21, var3 = 31 },
                new Foo<int> { var1 = 21, var2 = 22, var3 = 32 },
            };

            foreach (var bar in bars)
            {
                Console.WriteLine($"Var1: {bar.var1}, Var2: {bar.var2}, Var3: {bar.var3}");
            }
        }
    }
}
Risultato:

Nota: Una struttura generica può essere l'origine di tipi costruiti sia non gestiti che non gestiti. L'esempio precedente definisce una struttura generica Foo e presenta un tipo costruito non gestito.

Punti da ricordare:
  1. Questa funzione è un miglioramento delle prestazioni.
  2. I tipi di valore costruiti ora non sono gestiti se contengono solo campi di tipi non gestiti.
  3. Questa funzione significa che puoi fare cose come allocare istanze nello stack

Nel prossimo articolo parlerò di Stackaloc nelle espressioni nidificate in C# 8 con esempi. Qui, in questo articolo, provo a spiegare Tipi costruiti non gestiti in C# 8 con esempi. Spero che questo articolo ti piaccia.