Progettazione di parametri
Nota
Questo contenuto viene ristampato con l'autorizzazione di Pearson Education, Inc. da Framework Design Guidelines: Conventions, Idioms and Patterns for Reusable .NET Libraries, 2nd Edition. Tale edizione è stata pubblicata nel 2008 e il libro è stato completamente rivisto nella terza edizione. Alcune informazioni in questa pagina potrebbero non essere aggiornate.
Questa sezione fornisce linee guida generali sulla progettazione dei parametri, incluse le sezioni con linee guida per il controllo degli argomenti. Inoltre, è necessario fare riferimento alle linee guida descritte in Parametri di denominazione.
✔️ USARE il tipo di parametro meno derivato che fornisce la funzionalità richiesta dal membro.
Si supponga, ad esempio, di voler progettare un metodo che enumera una raccolta e stampa ogni elemento nella console. Un metodo di questo tipo deve accettare IEnumerable come parametro, non ArrayList o IList, ad esempio.
❌ NON usare parametri riservati.
Se in una versione futura sono necessari più input a un membro, è possibile aggiungere un nuovo overload.
❌ NON avere metodi esposti pubblicamente che accettano puntatori, matrici di puntatori o matrici multidimensionali come parametri.
I puntatori e le matrici multidimensionali sono relativamente difficili da usare correttamente. In quasi tutti i casi, è possibile riprogettare le API per evitare di accettare questi tipi come parametri.
✔️ ESEGUIRE l'inserimento di tutti i parametri out
in base a tutti i parametri per valore e ref
(esclusi le matrici di parametri), anche se comporta una incoerenza nell'ordinamento dei parametri tra overload (vedere Overload dei membri).
I parametri out
possono essere visualizzati come valori restituiti aggiuntivi, e raggrupparli insieme semplifica la comprensione della firma del metodo.
✔️ ESSERE coerenti nei parametri di denominazione durante l'override dei membri o l'implementazione dei membri dell'interfaccia.
Ciò consente di comunicare meglio la relazione tra i metodi.
Scelta tra enumerazione e parametri booleani
✔️ USARE le enumerazioni se altrimenti un membro avrebbe due o più parametri booleani.
❌ NON usare valori booleani, a meno che non si sia assolutamente certi che non ci sarà mai bisogno di più di due valori.
Le enumerazioni offrono spazio per l'aggiunta futura di valori, ma è necessario essere consapevoli di tutte le implicazioni dell'aggiunta di valori alle enumerazioni, che sono descritte in Enum Design.
✔️ PRENDERE IN CONSIDERAZIONE l'uso di valori booleani per i parametri del costruttore che sono realmente valori a due stati e vengono semplicemente usati per inizializzare le proprietà booleane.
Convalida degli argomenti
✔️ CONVALIDARE gli argomenti passati ai membri pubblici, protetti o implementati in modo esplicito. Generare System.ArgumentException, o una delle relative sottoclassi, se la convalida non riesce.
Si noti che la convalida effettiva non deve necessariamente verificarsi nel membro pubblico o protetto stesso. Potrebbe verificarsi a un livello inferiore in una routine privata o interna. Il punto principale è che l'intera superficie esposta agli utenti finali controlla gli argomenti.
✔️ GENERARE ArgumentNullException se viene passato un argomento Null e il membro non supporta argomenti Null.
✔️ CONVALIDARE i parametri di enumerazione DO.
Non presupporre che gli argomenti di enumerazione siano inclusi nell'intervallo definito dall'enumerazione. CLR consente di eseguire il cast di qualsiasi valore intero in un valore enumerazione anche se il valore non è definito nell'enumerazione.
❌ NON usare Enum.IsDefined per i controlli dell'intervallo di enumerazione.
✔️ TENERE PRESENTE che gli argomenti modificabili potrebbero essere stati modificati dopo la convalida.
Se il membro è sensibile alla sicurezza, è consigliabile creare una copia e quindi convalidare ed elaborare l'argomento.
Passaggio dei parametri
Dal punto di vista di una finestra di progettazione del framework, esistono tre gruppi principali di parametri: parametri per valore, parametri ref
e parametri out
.
Quando un argomento viene passato tramite un parametro per valore, il membro riceve una copia dell'argomento effettivo passato. Se l'argomento è un tipo valore, viene inserita una copia dell'argomento nello stack. Se l'argomento è un tipo riferimento, viene inserita una copia del riferimento nello stack. I linguaggi CLR più diffusi, ad esempio C#, VB.NET e C++, per impostazione predefinita passano parametri per valore.
Quando un argomento viene passato tramite un parametro ref
, il membro riceve un riferimento all'argomento effettivo passato. Se l'argomento è un tipo valore, viene inserito un riferimento all'argomento nello stack. Se l'argomento è un tipo riferimento, viene inserito nello stack un riferimento al riferimento. I parametri Ref
possono essere utilizzati per consentire al membro di modificare gli argomenti passati dal chiamante.
I parametri Out
sono simili ai parametri ref
, con alcune piccole differenze. Il parametro viene inizialmente considerato non assegnato e non può essere letto nel corpo del membro prima che venga assegnato un valore. Inoltre, è necessario assegnare un valore al parametro prima che venga restituito il membro.
❌ EVITARE l'uso di parametri out
o ref
.
L'uso di parametri out
o ref
richiede esperienza con i puntatori, comprendere in che modo i tipi di valore e i tipi di riferimento differiscono e gestiscono i metodi con più valori restituiti. Inoltre, la differenza tra i parametri out
e ref
non è ampiamente comprensibile. Gli architetti del framework che progettano per un pubblico generale non devono aspettarsi che gli utenti diventino esperti nell'uso di parametri out
o ref
.
❌ NON passare i tipi riferimento per riferimento.
Esistono alcune eccezioni limitate alla regola, ad esempio un metodo che può essere usato per scambiare i riferimenti.
Membri con numero variabile di parametri
I membri che possono accettare un numero variabile di argomenti vengono espressi fornendo un parametro di matrice. Ad esempio, String fornisce il metodo seguente:
public class String {
public static string Format(string format, object[] parameters);
}
Un utente può quindi chiamare il metodo String.Format, come indicato di seguito:
String.Format("File {0} not found in {1}",new object[]{filename,directory});
L'aggiunta della parola chiave params C# a un parametro di matrice modifica il parametro in un parametro di matrice chiamato params e fornisce un collegamento alla creazione di una matrice temporanea.
public class String {
public static string Format(string format, params object[] parameters);
}
In questo modo l'utente può chiamare il metodo passando gli elementi della matrice direttamente nell'elenco degli argomenti.
String.Format("File {0} not found in {1}",filename,directory);
Si noti che la parola chiave params può essere aggiunta solo all'ultimo parametro nell'elenco di parametri.
✔️ È consigliabile aggiungere la parola chiave params ai parametri della matrice se si prevede che gli utenti finali passino matrici con un numero ridotto di elementi. Se si prevede che molti elementi vengano passati in scenari comuni, gli utenti probabilmente non passeranno comunque questi elementi inline e quindi la parola chiave params non è necessaria.
❌ EVITARE di usare matrici params se il chiamante avrà quasi sempre l'input già in una matrice.
Ad esempio, i membri con parametri di matrice di byte non verrebbero quasi mai chiamati passando singoli byte. Per questo motivo, i parametri della matrice di byte in .NET Framework non usano la parola chiave params.
❌ NON usare matrici params se la matrice viene modificata dal membro che accetta il parametro della matrice params.
A causa del fatto che molti compilatori trasformano gli argomenti nel membro in una matrice temporanea nel sito di chiamata, la matrice potrebbe essere un oggetto temporaneo e pertanto eventuali modifiche alla matrice andranno perse.
✔️ PRENDERE IN CONSIDERAZIONE l'uso della parola chiave params in un overload semplice, anche se non è stato possibile usare un overload più complesso.
Chiedere se gli utenti potrebbero avere la matrice params in un overload anche se non era in tutti gli overload.
✔️ PROVARE a ordinare i parametri per consentire l'uso della parola chiave params.
✔️ VALUTARE la possibilità di fornire overload e percorsi di codice speciali per le chiamate con un numero ridotto di argomenti in API estremamente sensibili alle prestazioni.
In questo modo è possibile evitare di creare oggetti matrice quando l'API viene chiamata con un numero ridotto di argomenti. Formare i nomi dei parametri prendendo una forma singolare del parametro di matrice e aggiungendo un suffisso numerico.
È consigliabile eseguire questa operazione solo se si intende in modo speciale l'intero percorso del codice, non solo creare una matrice e chiamare il metodo più generale.
✔️ SI TENGA PRESENTE che null può essere passato come argomento dell'array params.
È necessario verificare che la matrice non sia Null prima dell'elaborazione.
❌ NON usare i metodi varargs
, altrimenti noti come puntini di sospensione.
Alcuni linguaggi CLR, ad esempio C++, supportano una convenzione alternativa per passare elenchi di parametri delle variabili denominati metodi varargs
. La convenzione non deve essere usata nei framework, perché non è conforme a CLS.
Parametri del puntatore
In generale, i puntatori non devono essere visualizzati nella superficie pubblica di un framework di codice gestito ben progettato. Nella maggior parte dei casi, i puntatori devono essere incapsulati. Tuttavia, in alcuni casi i puntatori sono necessari per motivi di interoperabilità e l'uso di puntatori in tali casi è appropriato.
✔️ FORNIRE un'alternativa per qualsiasi membro che accetta un argomento puntatore, perché i puntatori non sono conformi a CLS.
❌ EVITARE di eseguire un costoso controllo degli argomenti del puntatore.
✔️ SEGUIRE le convenzioni comuni relative ai puntatori durante la progettazione di membri con puntatori.
Ad esempio, non è necessario passare l'indice iniziale, perché è possibile usare un semplice aritmetico puntatore per ottenere lo stesso risultato.
Parti protette da copyright © 2005, 2009 Microsoft Corporation. Tutti i diritti sono riservati.
Ristampato con l'autorizzazione di Pearson Education, Inc. da Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2a edizione di Krzysztof Cwalina and Brad Abrams, pubblicato il 22 ottobre 2008 da Addison-Wesley Professional nella collana Microsoft Windows Development Series.