Istruzioni per l'uso dei tipi di valore

Un tipo di valore descrive un valore che è rappresentato come sequenza di bit archiviati nello stack. Per una descrizione di tutti i tipi di dati incorporati in .NET Framework, vedere Tipi di valore. In questa sezione vengono fornite istruzioni per l'uso dei tipi di valore di struttura (struct) ed enumerazione (enum).

Istruzioni per l'uso delle strutture

È consigliabile utilizzare un valore struct per i tipi che soddisfano uno dei seguenti criteri:

  • Funzionano come tipi primitivi
  • Dispongono di una dimensione dell'istanza inferiore a 16 byte
  • Sono immutabili
  • Richiedono la semantica dei valori.

Nell'esempio seguente viene illustrata una struttura definita in modo corretto.

Public Structure Int32 
   Implements IFormattable 
   Implements IComparable
   Public Const MinValue As Integer = -2147483648
   Public Const MaxValue As Integer = 2147483647
   
   Private intValue As Integer

   Overloads Public Shared Function ToString(i As Integer) As String
      ' Insert code here.
   End Function 
   
   Overloads Public Function ToString(ByVal format As String, ByVal 
         formatProvider As IFormatProvider) As String Implements  
         IFormattable.ToString
      ' Insert code here.
   End Function 
   
   Overloads Public Overrides Function ToString() As String
      ' Insert code here.
   End Function 
   Public Shared Function Parse(s As String) As Integer
      ' Insert code here.
      Return 0
   End Function
   
   Public Overrides Function GetHashCode() As Integer
      ' Insert code here.
      Return 0
   End Function 
   
   Public Overrides Overloads Function Equals(obj As Object) As Boolean 
      ' Insert code here.
      Return False
   End Function 
   
   Public Function CompareTo(obj As Object) As Integer Implements 
         IComparable.CompareTo
      ' Insert code here.
      Return 0
   End Function 
End Structure 
[C#]
public struct Int32: IComparable, IFormattable
{ 
   public const int MinValue = -2147483648;
   public const int MaxValue = 2147483647;
   
   public static string ToString(int i) 
   {
      // Insert code here.
   }

   public string ToString(string format, IFormatProvider formatProvider) 
   {
      // Insert code here.
   }

   public override string ToString() 
   {
      // Insert code here.
   }

   public static int Parse(string s)
   {
      // Insert code here.
      return 0;
   }

   public override int GetHashCode()
   {
      // Insert code here.
      return 0;
   }

   public override bool Equals(object obj)
   {
      // Insert code here.
      return false;
   }

   public int CompareTo(object obj)
   {
      // Insert code here.
      return 0;
   }

}
  • Non fornire un costruttore predefinito per un tipo struct. In C# non è consentito utilizzare un tipo struct con un costruttore predefinito. Nell'ambiente di esecuzione viene inserito automaticamente un costruttore che inizializza tutti i valori su uno stato zero. È così possibile creare matrici di strutture senza eseguire il costruttore su ciascuna istanza. Non impostare un tipo struct come dipendente da un costruttore chiamato per ciascuna istanza. È possibile creare istanze delle strutture con un valore zero senza eseguire un costruttore. È inoltre opportuno progettare un tipo struct per uno stato in cui, per essere validi, tutti i dati delle istanze devono essere impostati su zero, false o null, in base alle esigenze.

Istruzioni per l'uso degli enum

Le istruzioni per l'uso delle enumerazioni sono definite dalle regole riportate di seguito.

  • Non utilizzare un suffisso Enum sui tipi enum.

  • Utilizzare un tipo enum per tipizzare in modo sicuro parametri, proprietà e tipi restituiti. Definire sempre valori enumerati utilizzando un enum, se vengono utilizzati in un parametro o in una proprietà. In questo modo vengono indicati agli strumenti di sviluppo i valori possibili di una proprietà o di un parametro. Nell'esempio seguente viene illustrato come definire un tipo enum.

    Public Enum FileMode
       Append
       Create
       CreateNew
       Open
       OpenOrCreate
       Truncate
    End Enum
    [C#]
    public enum FileMode
    {
       Append,
       Create,
       CreateNew,
       Open,
       OpenOrCreate,
       Truncate
    }
    

    Nell'esempio riportato di seguito viene illustrato il costruttore per un oggetto FileStream che utilizza l'enumerazione FileMode.

    Public Sub New(ByVal path As String, ByVal mode As FileMode);
    [C#]
    public FileStream(string path, FileMode mode);
    
  • Utilizzare un enum anziché costanti finali static.

  • Non utilizzare un enum per gli insiemi aperti, ad esempio la versione del sistema operativo.

  • Utilizzare la classe System.FlagsAttribute per creare un attributo personalizzato per un enum solo se deve essere eseguita un'operazione OR bit per bit su valori numerici. Per i valori enum utilizzare potenze di due in modo da semplificarne la combinazione. L'attributo viene applicato nell'esempio di codice riportato di seguito.

    <Flags()>
    Public Enum WatcherChangeTypes
       Created = 1
       Deleted = 2
       Changed = 4
       Renamed = 8
       All = Created Or Deleted Or Changed Or Renamed
    End Enum 
    [C#]
    [Flags()]
    public enum WatcherChangeTypes
    {
       Created = 1,
       Deleted = 2,
       Changed = 4,
       Renamed = 8,
       All = Created | Deleted | Changed | Renamed
    };
    

    **Nota   **Un'eccezione a questa regola è l'incapsulamento di un'interfaccia API Win32. In genere le definizioni interne provengono da un'intestazione Win32. È possibile lasciarle con la convenzione Win32, che di solito prevede tutte le lettere maiuscole.

  • Provare a fornire costanti denominate per le combinazioni di flag utilizzate frequentemente. L'utilizzo di operazioni OR bit per bit costituisce una funzionalità avanzata che non dovrebbe essere richiesta per operazioni semplici, come illustrato nell'esempio di enumerazione riportato di seguito.

    <Flags()> _
    Public Enum FileAccess
       Read = 1
       Write = 2
       ReadWrite = Read Or Write
    End Enum 
    [C#]
    [Flags()]
    public enum FileAccess
    {
       Read = 1,
       Write = 2,
       ReadWrite = Read | Write,
    }
    
  • Utilizzare il tipo Int32 come tipo sottostante di un enum a meno che non sia soddisfatta una delle condizioni indicate di seguito.

    • L'enum rappresenta i flag e attualmente sono disponibili oltre 32 flag oppure l'enum potrebbe espandersi fino a includere numerosi flag in futuro.
    • Il tipo deve essere diverso da int per la compatibilità con le versioni precedenti.
  • Non presupporre che gli argomenti enum saranno compresi nell'intervallo definito. Il cast di un valore integer in un enum costituisce un'operazione valida anche se il valore non è definito nel tipo enum. Eseguire la convalida degli argomenti come viene mostrato nell'esempio di codice riportato di seguito.

    Public Sub SetColor(newColor As Color)
       If Not [Enum].IsDefined(GetType(Color), newColor) Then
          Throw New ArgumentOutOfRangeException()
       End If 
    End Sub
    [C#]
    public void SetColor (Color color)
    {
       if (!Enum.IsDefined (typeof(Color), color) 
          throw new ArgumentOutOfRangeException();
    }
    

Vedere anche

Istruzioni di progettazione per gli sviluppatori di librerie di classi | Convenzioni di denominazione per i tipi di enumerazione | Tipi di valore | Enumerazioni