Condividi tramite


Overload dei membri

Nella firma di un membro sono inclusi il nome e l'elenco dei parametri. La firma di ciascun membro deve essere univoca nell'ambito dello stesso tipo. I membri possono avere lo stesso nome, purché i rispettivi elenchi di parametri siano diversi. Quando due o più membri di un tipo appartengono alla stessa tipologia (metodo, proprietà, costruttore e così via) e hanno lo stesso nome, ma elenchi di parametri differenti, si verifica un caso di overload del membro. Ad esempio, la classe Array contiene due metodi CopyTo. Il primo accetta una matrice e un valore Int32 e il secondo accetta una matrice e un valore Int64.

NotaNota

La modifica del tipo restituito di un metodo non determina l'univocità del metodo, come definito nella specifica di Common Language Runtime.Non è possibile definire overload che variano solo in base al tipo restituito.

I membri in overload dovrebbero fornire variazioni relative alla stessa funzionalità. Ad esempio, non sarebbe corretto definire un tipo con due membri CopyTo, di cui il primo copia i dati in una matrice e il secondo copia i dati in un file. È pratica comune fornire overload che accettano pochi parametri, o nessun parametro, e che sono facili da utilizzare. Questi membri chiamano overload più potenti, ma richiedono una maggiore esperienza per un utilizzo corretto. Gli overload facili da utilizzare supportano scenari comuni passando valori predefiniti agli overload complessi. La classe File, ad esempio, fornisce overload per il metodo Open. L'overload semplice Open accetta un percorso e una modalità file e chiama l'overload Open, che accetta un percorso, una modalità file e i parametri di accesso e condivisione file, oltre a fornire i valori predefiniti comunemente utilizzati per questi parametri. Gli sviluppatori che non hanno l'esigenza della flessibilità offerta dall'overload complesso non devono apprendere i modelli di accesso e condivisione file per poter aprire un file.

Per una maggiore facilità di manutenzione e controllo delle versioni, gli overload più semplici dovrebbero utilizzare gli overload complessi per l'esecuzione di azioni. La funzionalità sottostante non deve essere implementata in più posizioni.

Linee guida per l'overload

Le linee guida riportate di seguito consentono di assicurarsi che i membri in overload siano progettati correttamente.

Provare a utilizzare nomi di parametro descrittivi per indicare il valore predefinito utilizzato dagli overload più semplici.

Questa linea guida è applicabile principalmente ai parametri Boolean. Il nome di parametro dell'overload più complesso dovrebbe indicare il valore predefinito fornito dall'overload più semplice descrivendo l'azione o lo stato opposto. Ad esempio, la classe String fornisce i seguenti overload:

Overloads Public Shared Function Compare( _
   ByVal strA As String, _
   ByVal strB As String _
) As Integer

Overloads Public Shared Function Compare( _
   ByVal strA As String, _
   ByVal strB As String, _
   ByVal ignoreCase As Boolean _
) As Integer
public static int Compare(
   string strA,
   string strB
);

public static int Compare(
   string strA,
   string strB,
   bool ignoreCase
);

Il secondo overload fornisce un parametro Boolean denominato ignoreCase. Questo indica che l'overload più semplice rispetta la distinzione tra maiuscole e minuscole ed è necessario utilizzare l'overload più complesso solo quando si desidera ignorare questa distinzione. In generale, il valore predefinito dovrebbe essere false.

Evitare di utilizzare negli overload nomi di parametro che variano arbitrariamente. Se un parametro in un determinato overload rappresenta lo stesso input di un parametro in un altro overload, tali parametri devono avere lo stesso nome.

Ad esempio, evitare di specificare quanto segue:

Public Sub Write(message as String, stream as FileStream)
End Sub
Public Sub Write(line as String, file as FileStream, closeStream as Boolean)
End Sub
public void Write(string message, FileStream stream){}
public void Write(string line, FileStream file, bool closeStream){}
public:
    void Write(String^ message, FileStream^ stream){}
    void Write(String^ line, FileStream^ file, bool closeStream){}

Di seguito è riportata la definizione corretta per questi overload:

Public Sub Write(message as String, stream as FileStream)
End Sub
Public Sub Write(message as String, stream as FileStream, _
    closeStream as Boolean)
End Sub
public void Write(string message, FileStream stream){}
public void Write(string message, FileStream stream, bool closeStream){}
public:
    void Write(String^ message, FileStream^ stream){}
    void Write(String^ message, FileStream^ stream, bool closeStream){}

Mantenere la coerenza nell'ordinamento dei parametri per i membri in overload. I parametri con lo stesso nome devono occupare la stessa posizione in tutti gli overload.

Ad esempio, evitare di specificare quanto segue:

Public Sub Write( message as String, stream as FileStream)
End Sub
Public Sub Write(stream as FileStream, message as String, _
    closeStream as Boolean)
End Sub
public void Write(string message, FileStream stream){}
public void Write(FileStream stream,  string message, bool closeStream){}
public:
    void Write(String^ message, FileStream^ stream){}
    void Write(FileStream^ stream, String^ message, bool closeStream){}

Di seguito è riportata la definizione corretta per questi overload:

Public Sub Write(message as String, stream as FileStream)
End Sub
Public Sub Write(message as String, stream as FileStream, _
    closeStream as Boolean)
End Sub
public void Write(string message, FileStream stream){}
public void Write(string message, FileStream stream, bool closeStream){}
public:
    void Write(String^ message, FileStream^ stream){}
    void Write(String^ message, FileStream^ stream, bool closeStream){}

Questa linea guida presenta due vincoli:

  • Se un overload accetta un elenco di argomenti variabili, tale elenco deve essere riportato come ultimo parametro.

  • Se l'overload accetta parametri out, per convenzione tali parametri dovrebbero apparire per ultimi.

Se è richiesta l'estensibilità, rendere virtuale solo l'overload più lungo (Overridable in Visual Basic). Gli overload più brevi devono semplicemente eseguire chiamate a un overload più lungo.

Nell'esempio di codice riportato di seguito viene illustrata questa pratica.

Public Sub Write(message as String, stream as FileStream)
    Me.Write(message, stream, false)
End Sub

Public Overridable Sub Write( _
    message as String, stream as FileStream, closeStream as Boolean)
    ' Do work here.
End Sub
public void Write(string message, FileStream stream)
{
    this.Write(message, stream, false);
}
public virtual void Write(string message, FileStream stream, bool closeStream)
{
    // Do work here.
}
public:
    void Write(String^ message, FileStream^ stream)
    {
        this->Write(message, stream, false);
    }

    virtual void Write(String^ message, FileStream^ stream, bool closeStream)
    {
        // Do work here.
    }

Non utilizzare modificatori ref o out per eseguire l'overload di membri.

Ad esempio, evitare di specificare quanto segue:

Public Sub Write(message as String,  count as Integer)


...


Public Sub Write(message as String, ByRef count as Integer)
public void Write(string message, int count)


...


public void Write(string message, out int count)
public:
    void Write(String^ message, int count)


...


void Write(String^ message, int% count)

In generale, se si verifica un caso di questo tipo, è molto probabile che sia dovuto a un problema di progettazione a livello più profondo. Valutare l'opportunità di rinominare uno dei membri per fornire ulteriori informazioni sull'esatta azione eseguita dal metodo.

Consentire il passaggio di null (Nothing in Visual Basic) per argomenti facoltativi. Se un metodo accetta argomenti facoltativi che sono tipi di riferimento, consentire il passaggio di null per indicare che dovrebbe essere utilizzato il valore predefinito. In questo modo si evita di dover verificare la presenza di null prima di chiamare un membro.

Nell'esempio riportato di seguito gli sviluppatori non devono verificare la presenza di null.

Public Sub CopyFile (source as FileInfo, _
    destination as DirectoryInfo, _
    newName as string)

    If newName Is Nothing
        InternalCopyFile(source, destination) 
    Else
        InternalCopyFile(source, destination, newName)
    End If
End Sub
public void CopyFile (FileInfo source, DirectoryInfo destination, string newName)
{
    if (newName == null)
    {
        InternalCopyFile(source, destination);
    }
    else
    {
        InternalCopyFile(source, destination, newName);
    }
}
public:
    void CopyFile(FileInfo^ source, DirectoryInfo^ destination, String^ newName)
    {
        if (newName == nullptr)
       {
            InternalCopyFile(source, destination);
        }
        else
        {
            InternalCopyFile(source, destination, newName);
        }
    }

Utilizzare l'overload dei membri anziché definire membri con argomenti predefiniti, che non sono conformi a CLS e non possono essere utilizzati da alcuni linguaggi.

Nel codice riportato di seguito viene illustrato un esempio di progettazione non corretta di un metodo.

Public Sub Rotate (data as Matrix, Optional degrees as Integer = 180)
' Do rotation here
End Sub

Il codice dovrebbe essere riprogettato come due overload, con l'overload più semplice che fornisce il valore predefinito, come illustrato nel seguente esempio.

Overloads Public Sub Rotate (data as Matrix)
    Rotate(data, 180)
End Sub

Overloads Public Sub Rotate (data as Matrix, degrees as Integer)
' Do rotation here
End Sub

Portions Copyright 2005 Microsoft Corporation. Tutti i diritti riservati.

Portions Copyright Addison-Wesley Corporation. Tutti i diritti riservati.

Per ulteriori informazioni sulle linee guida di progettazione, vedere “le linee guida di progettazione di Framework: Idiomi convenzioni, e modelli per libro raccolte riutilizzabili .NET„ di Krzysztof Cwalina e brad Abrams, emessi da Addison-Wesley, 2005.

Vedere anche

Altre risorse

Linee guida di progettazione dei membri

Linee guida di progettazione per lo sviluppo di librerie di classi