Compartilhar via


Projeto de Parâmetros

Observação

Esse conteúdo é reimpresso por permissão da Pearson Education, Inc. das Diretrizes de Design da Estrutura: Convenções, Idiomas e Padrões para Bibliotecas .NET Reutilizáveis, 2ª Edição. Essa edição foi publicada em 2008, e desde então o livro foi totalmente revisado na terceira edição. Algumas das informações nesta página podem estar desatualizadas.

Esta seção fornece diretrizes amplas sobre o design de parâmetros, incluindo seções com diretrizes para verificar argumentos. Além disso, você deve se referir às diretrizes descritas em Parâmetros de Nomenclatura.

✔️ Use o tipo de parâmetro menos derivado que fornece a funcionalidade exigida pelo membro.

Por exemplo, suponha que você queira criar um método que enumera uma coleção e imprime cada item no console. Esse método deve ser usado IEnumerable como o parâmetro, não ArrayList ou IList, por exemplo.

❌ NÃO use parâmetros reservados.

Se mais entradas para um membro forem necessárias em alguma versão futura, uma nova sobrecarga poderá ser adicionada.

❌ NÃO exponha publicamente métodos que levam ponteiros, matrizes de ponteiros ou matrizes multidimensionais como parâmetros.

Ponteiros e matrizes multidimensionais são relativamente difíceis de usar corretamente. Em quase todos os casos, as APIs podem ser reprojetadas para evitar o uso desses tipos como parâmetros.

✔️ Coloque todos os parâmetros out seguindo todos os valores e parâmetros ref (excluindo matrizes de parâmetros), mesmo que isso resulte em uma inconsistência na ordenação de parâmetros entre sobrecargas (consulte Sobrecarga de membro).

Os out parâmetros podem ser vistos como valores de retorno extras e agrupá-los torna a assinatura do método mais fácil de entender.

✔️ Seja consistente na nomeação dos parâmetros ao substituir membros ou implementar membros da interface.

Isso comunica melhor a relação entre os métodos.

Escolhendo entre parâmetros Enum e Boolean

✔️ Use enumerações se um membro tiver dois ou mais parâmetros boolianos.

❌ NÃO use boolianos, a menos que você tenha certeza absoluta de que nunca haverá necessidade de mais de dois valores.

As enumerações oferecem espaço para futura adição de valores, mas você deve estar ciente de todas as implicações de adição de valores a enumerações, que são descritas no Design de Enum.

✔️ CONSIDERE o uso de Booleans para parâmetros de construtor que são verdadeiramente valores de dois estados e são simplesmente usados para inicializar propriedades boolianas.

Validando argumentos

✔️ Valide argumentos passados para membros públicos, protegidos ou explicitamente implementados. Gere System.ArgumentException ou uma de suas subclasses, se a validação falhar.

Observe que a validação real não precisa necessariamente acontecer no próprio membro público ou protegido. Isso pode acontecer em um nível inferior em alguma rotina privada ou interna. O ponto principal é que toda a área de superfície exposta aos usuários finais verifica os argumentos.

✔️ Gere ArgumentNullException se um argumento nulo for passado e o membro não oferecer suporte a argumentos nulos.

✔️ Valide parâmetros de enumeração.

Não suponha que os argumentos de enumeração estarão no intervalo definido pela enumeração. O CLR permite converter qualquer valor inteiro em um valor de enumeração mesmo se o valor não estiver definido na enumeração.

❌ NÃO utilize Enum.IsDefined para verificar intervalos de enum.

✔️ Lembre-se de que argumentos mutáveis podem ter sido alterados depois de validados.

Se o membro for sensível à segurança, você será incentivado a fazer uma cópia e, em seguida, validar e processar o argumento.

Passagem de parâmetro

Na perspectiva de um designer de estrutura, há três grupos principais de parâmetros: parâmetros por valor, parâmetros ref e parâmetros out.

Quando um argumento é passado por um parâmetro por valor, o membro recebe uma cópia do argumento real passado. Se o argumento for um tipo de valor, uma cópia do argumento será colocada na pilha. Se o argumento for um tipo de referência, uma cópia da referência será colocada na pilha. Por padrão, as linguagens CLR mais populares, como C#, VB.NET e C++, passam os parâmetros por valor.

Quando um argumento é passado por um ref parâmetro, o membro recebe uma referência ao argumento real passado. Se o argumento for um tipo de valor, uma referência ao argumento será colocada na pilha. Se o argumento for um tipo de referência, uma cópia da referência será colocada na pilha. Ref os parâmetros podem ser usados para permitir que o membro modifique os argumentos passados pelo chamador.

Out os parâmetros são semelhantes aos ref parâmetros, com algumas pequenas diferenças. O parâmetro é inicialmente considerado não atribuído e não pode ser lido no corpo do membro antes de receber algum valor. Além disso, o parâmetro deve ser atribuído algum valor antes que o membro retorne.

❌ EVITE usar out ou ref parâmetros.

Usar out ou ref parâmetros requer experiência com ponteiros, entender como tipos de valor e tipos de referência diferem e lidar com métodos com vários valores retornados. Além disso, a diferença entre parâmetros out e ref não é amplamente compreendida. Os arquitetos de estrutura que projetam para um público-alvo geral não devem esperar que os usuários se tornem proficientes em trabalhar com out ou ref parâmetros.

❌ NÃO passe tipos de referência por referência.

Há algumas exceções limitadas à regra, como um método que pode ser usado para trocar referências.

Membros com número variável de parâmetros

Os membros que podem receber um número variável de argumentos são expressos fornecendo um parâmetro de matriz. Por exemplo, String fornece o seguinte método:

public class String {
    public static string Format(string format, object[] parameters);
}

Um usuário pode chamar o String.Format método da seguinte maneira:

String.Format("File {0} not found in {1}",new object[]{filename,directory});

Adicionar a palavra-chave params C# a um parâmetro de matriz altera o parâmetro para um parâmetro de matriz de parâmetros chamado params e fornece um atalho para a criação de uma matriz temporária.

public class String {
    public static string Format(string format, params object[] parameters);
}

Isso permite que o usuário chame o método passando os elementos da matriz diretamente na lista de argumentos.

String.Format("File {0} not found in {1}",filename,directory);

Observe que a palavra-chave params pode ser adicionada somente ao último parâmetro na lista de parâmetros.

✔️ CONSIDERE adicionar a palavra-chave params aos parâmetros de matriz se você espera que os usuários finais passem matrizes com um pequeno número de elementos. Se é esperado que muitos elementos sejam passados em cenários comuns, os usuários provavelmente não passarão esses elementos embutidos de e, portanto, a palavra-chave params não é necessária.

❌ EVITE usar matrizes de parâmetros se o chamador quase sempre tiver a entrada já em uma matriz.

Por exemplo, membros com parâmetros de matriz de bytes quase nunca seriam chamados passando bytes individuais. Por esse motivo, os parâmetros de matriz de bytes no .NET Framework não usam a palavra-chave params.

❌ NÃO use matrizes de parâmetros se a matriz for modificada pelo membro que usa o parâmetro de matriz params.

Devido ao fato de que muitos compiladores transformam os argumentos para o membro em uma matriz temporária no site de chamada, a matriz pode ser um objeto temporário e, portanto, todas as modificações na matriz serão perdidas.

✔️ Considere o uso da palavra-chave params em uma sobrecarga simples, mesmo que uma sobrecarga mais complexa não possa usá-la.

Pergunte a si mesmo se os usuários valorizariam ter a matriz params em uma sobrecarga, mesmo que não estivesse em todas as sobrecargas.

✔️ TENTE ordenar parâmetros para tornar possível usar a palavra-chave params.

✔️ CONSIDERE fornecer sobrecargas especiais e caminhos de código para chamadas que utilizam um pequeno número de argumentos em APIs com extrema sensibilidade ao desempenho.

Isso possibilita evitar a criação de objetos de matriz quando a API é chamada com um pequeno número de argumentos. Forme os nomes dos parâmetros tomando uma forma singular do parâmetro de matriz e adicionando um sufixo numérico.

Você só deverá fazer isso se quiser diferenciar o caminho de código inteiro, não apenas criar uma matriz e chamar o método mais geral.

✔️ Lembre-se que nulo pode ser passado como um argumento de matriz params.

Você deve validar que a matriz não é nula antes do processamento.

❌ NÃO use os métodos varargs, também conhecidos como reticências.

Algumas linguagens CLR, como C++, dão suporte a uma convenção alternativa para passar listas de parâmetros variáveis chamadas varargs métodos. A convenção não deve ser usada em frameworks, pois não é compatível com CLS.

Parâmetros de Ponteiro

Em geral, os ponteiros não devem aparecer na área de superfície pública de uma estrutura de código gerenciada bem projetada. Na maioria das vezes, os ponteiros devem ser encapsulados. No entanto, em alguns casos, os ponteiros são necessários por motivos de interoperabilidade e o uso de ponteiros nesses casos é apropriado.

✔️ Forneça uma alternativa para qualquer membro que use um argumento de ponteiro, pois os ponteiros não são compatíveis com CLS.

❌ EVITE fazer uma verificação cara de argumentos de ponteiro.

✔️ Siga convenções comuns relacionadas ao ponteiro ao criar membros com ponteiros.

Por exemplo, não é necessário passar o índice inicial, pois a aritmética de ponteiro simples pode ser usada para realizar o mesmo resultado.

Partes © 2005, 2009 Microsoft Corporation. Todos os direitos reservados.

Reimpresso por permissão da Pearson Education, Inc. de Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition de Krzysztof Cwalina e Brad Abrams, publicado em 22 de outubro de 2008 pela Addison-Wesley Professional como parte da série Microsoft Windows Development Series.

Consulte também