Devo usar o padrão (Foo), Foo.Empty, ou null?
-
06-07-2019 - |
Pergunta
Assim, C # agora permite que você use default(Foo)
para obter um reconhecido "não preenchido ainda" / instância vazia de uma classe - Eu não tenho certeza se ele é exatamente o mesmo que new Foo()
ou não. Muitas classes de biblioteca também implementar uma propriedade Foo.Empty
, que retorna uma instância similar. E, claro, qualquer tipo de referência pode apontar para null
. Então, realmente, qual é a diferença? Quando é um certo ou errado? O que é mais consistente, ou executa melhor? Que exames devo usar ao verificar se um objeto é conceitualmente "não está pronto para o horário nobre"? Nem todo mundo tem Foo.IsNullOrEmpty()
.
Solução
default(Foo)
irá retornar nulo quando Foo
é um tipo de classe, de zero, onde Foo
é um tipo de valor (como int), e uma instância de Foo
com todos os campos inicializados com seus respectivos valores default()
onde Foo
é um struct. Foi adicionado à linguagem de modo que os genéricos poderiam apoiar ambos os tipos de valor e de referência - mais informações no MSDN
Use default(Foo)
quando você está testando um T no contexto de SomeClass<T>
ou MyMethod<T>
e você não sabe se T será tipo de valor, um tipo de classe ou um struct.
Caso contrário, null deve significar "desconhecido", e esvaziar deve significar "Eu sei que isto está vazia". Use o padrão Foo.Empty se você realmente precisa de um vazio - mas não nulo - instância de sua classe; por exemplo. String.Empty
como uma alternativa para ""
Se você precisa para inicializar algumas variáveis ??para a cadeia vazia.
Use nulo se você sabe que você está trabalhando com tipos de referência (classes), não há genéricos envolvidos, e você está testando explicitamente referências não inicializadas.
Outras dicas
Quando você sabe o tipo real envolvido, ou se você tem um parâmetro de tipo constrangidos com ": class". Que é mais simples de usar o valor conhecido (null, 0 etc)
Quando você só tem um parâmetro de tipo que é irrestrita ou restrita para além de ser um tipo de referência, você precisa usar default (T).
default(Foo)
funciona para ambos os tipos de valor e tipos de referência. New Foo(), null
e Foo.Empty()
não. Isso o torna uma boa escolha para uso com tipos genéricos, por exemplo, quando você não pode saber que você está lidando com. Mas na maioria dos casos-tipo de referência, null
é provavelmente bom o suficiente.