aceitar objeto como um parâmetro é aceitável?
-
12-09-2019 - |
Pergunta
Vamos dizer que eu tenho uma caixa de texto ou qualquer outra forma de entrada que pede um número de segurança social. Eu quero notar que o SSN é um exemplo puro Eu simplesmente pensado a partir de agora. Esta entrada será, naturalmente, armazenado como uma string inicialmente.
string s = Console.ReadLine();
Vamos dizer que eu quero ter um método que valida um SSN e pode ser usado durante todo o meu código em todos os tipos de lugares. Heck, eu poderia até chamar o método em uma variável que não tenha sido determinado pelo usuário-entrada.
Será isto aceitável?
public bool IsValidSSN(Object SSN)
{
int mySSN;
if(Int.Parse(SSN == false)
{
mySSN = Convert.toInt32(SSN);
}
...
}
Ou você cara insistem que eu pedir um tipo de dados específico, por exemplo
public bool IsValidSSN(int SSN)
{
...
}
e por isso eu sou obrigado a converter a entrada para o tipo de dados correto antes que eu chame o método nela.
BTW: Eu não estou perguntando como fazer um código IsValidSSN adequada :) Eu só queria dar um exemplo do que eu quis dizer quando eu disse: Posso aceitar o tipo de dados objeto como um parâmetro ou devo tentar evitá-lo?
Solução
Se você deve aceitar um objeto que eu teria pelo menos sobrecargas do método que levam parâmetros rigidez. Em seguida, ter o objeto variantes alimentam esses métodos.
public bool IsValidSSN(object ssn) {
...
IsValidSSN(Convert.ToInt32(ssn));
...
}
public bool IsValidSSN(int ssn) {
...
}
Outras dicas
Depende completamente de seu projeto e onde você quer que sua validação a ocorrer. Realmente fundamentalmente depende de sua arquitetura geral e sua hierarquia de classe. Não é errado fazê-lo de qualquer forma; apenas a certeza de que é o caminho que se encaixa com o seu projeto arquitetônico.
Não vejo valor em aceitar um objeto neste caso. Pense em como você espera que a função de trabalho. (É claro que você não tem, uma vez que o código que você postou não trabalho). Eu acho que você está planejando algo como isto:
if (SSN is string)
SSN = Convert.toInt32(SSN);
else if (SSN is TextBox)
SSN = Convert.toInt32(SSN.Value);
else /* etc */
Como é que melhor do que:
bool isValidSSN(int SSN) { /* real valuation code */ }
bool IsValidSSN(String SSN) { return isValidSSN(Convert.toInt32(SSN)); }
bool IsValidSSN(TextBox SSN) { return isValidSSN(Convert.toInt32(SSN.Value)); }
Os métodos sobrecarregados são mais simples e mais rápido, uma vez que mais a decisão sobre o que fazer a partir de tempo de execução para a compilação.
No seu exemplo acima, é muito mais fácil de criar um IsValidSSN digitado. Geralmente eu acho que a digitação reduz erros e flexibilidade.
Em circunstâncias em que a flexibilidade se primordial em seguida, usando objetos é provavelmente a melhor escolha, mas espera enfrentar algumas exceções confronto elenco nos logs.
Para todos os outros casos, ser rigoroso com a sua digitação, ou escrevê-lo em python.
Pessoalmente, gostaria de fazer uma classe de SSN e ser capaz de pedir que SSN se era válido ou não. É importante ter classes que representam diretores em sua lógica de negócios. Isto é muito, por exemplo, o que você pode fazer com algo que exige mais de validação como uma classe de cartão de crédito. Entregar ao redor de objetos não é o melhor, se você pode evitá-lo e entregar em torno de algo que é um dos principais na sua lógica de negócios como um primitivo é ruim também (sua arquitetura faz SSN1 + SSN2 = SSN3 perfeitamente válida, mesmo que em lógica de negócios, é um disparate ).
Neste caso, eu diria que foi inaceitável. E se a entrada tem traços, ou algum outro caractere de separação (por exemplo: ### - ## - ####)? Você, obviamente, não seria capaz de analisar o valor como um inteiro, mas o valor ainda seria válido. Que tal usar uma expressão regular, em vez de garantir o valor é o que você desejar.
Em termos de usar o "objeto" tipo como um parâmetro, este é completamente válido em muitos casos. Na verdade, ele é usado em todo o .NET Framework (olhada delegados de evento):
public void Control_MouseOver(object sender, MouseEventArgs e){}
Este seria um caso simples de Boxe / Unboxing, o que era realmente a única maneira de realizar operações "genéricos" à variáveis ??até .NET 2.0.
Você também pode usar genéricos para resolver este problema sem a necessidade de casting. Se você criar uma interface que implementa algo como INumeric (Eu não sei se essa é a interface real) ou IComparable você deve ser capaz de executar a operação de uma forma mais elegante:
bool pública IsValidSNN (INumeric SSN) {}