Em C #, digamos que você deseja extrair um valor de PropertyC neste exemplo e ObjectA, PropertyA e PropertyB podem ser nulos.
ObjectA.PropertyA.PropertyB.PropertyC
Como posso obter PropertyC com segurança com o mínimo de código?
Agora eu verificaria:
if(ObjectA != null && ObjectA.PropertyA !=null && ObjectA.PropertyA.PropertyB != null)
{
// safely pull off the value
int value = objectA.PropertyA.PropertyB.PropertyC;
}
Seria bom fazer algo mais parecido com isso (pseudo-código).
int value = ObjectA.PropertyA.PropertyB ? ObjectA.PropertyA.PropertyB : defaultVal;
Possivelmente, ainda mais colapsou com um operador de coalescência nula.
EDITAR Originalmente, eu disse que meu segundo exemplo era como js, mas eu mudei para psuedo-code, pois foi corretamente apontado que não funcionaria em js.
ObjectA
ouPropertyA
forem nulos.Respostas:
Em C # 6, você pode usar o Operador Condicional Nulo . Portanto, o teste original será:
fonte
value
igual a sePropertyC
for nulo? ou sePropertyB
for nulo? e seObject A
for nulo?null
. Começa da esquerda para a direita. Sem o açúcar sintático, isso é equivalente a uma série de declarações if em queif(propertyX == null) {value = null} else if (propertyY == null){ value = null} else if......
a última expressão eventual sendoif(propertyZ != null) { value = propertyZ }
Método de extensão curta:
Usando
Este método de extensão simples e muito mais você pode encontrar em http://devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/
EDITAR:
Depois de usá-lo por um momento, acho que o nome apropriado para esse método deveria ser IfNotNull () em vez de With () original.
fonte
Você pode adicionar um método à sua classe? Se não, você já pensou em usar métodos de extensão? Você pode criar um método de extensão para o seu tipo de objeto chamado
GetPropC()
.Exemplo:
Uso:
A propósito, isso pressupõe que você esteja usando o .NET 3 ou superior.
fonte
A maneira como você está fazendo é correta.
Você pode usar um truque como o descrito aqui , usando expressões Linq:
Mas é muito mais lento do que verificar manualmente cada propriedade ...
fonte
Refatorar para observar a Lei de Demeter
fonte
Atualização de 2014: C # 6 tem um novo operador
?.
chamado 'navegação segura' ou 'propagação nula'Leia http://blogs.msdn.com/b/jerrynixon/archive/2014/02/26/at-last-c-is-getting-sometimes-called-the-safe-navigation-operator.aspx para obter detalhes
Este tem sido um pedido extremamente popular https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/3990187-add-operator-to-c-?tracking_code=594c10a522f8e9bc987ee4a5e2c0b38d
fonte
Obviamente, você está procurando pela Mônada Anulável :
torna-se
Isso retorna
null
, se alguma das propriedades anuláveis for nula; caso contrário, o valor deValue
.Métodos de extensão LINQ:
fonte
SelectMany
método de extensão é usado pelafrom ... in ... from ... in ...
sintaxe.Supondo que você tenha valores vazios de tipos, uma abordagem seria esta:
Sou um grande fã de C #, mas uma coisa muito boa no novo Java (1.7?) É o.? operador:
fonte
Este código é "a menor quantidade de código", mas não a prática recomendada:
fonte
Quando preciso encadear chamadas como essa, conto com um método auxiliar que criei, TryGet ():
No seu caso, você o usaria assim:
fonte
Eu vi algo no novo C # 6.0, isso é usando '?' em vez de verificar
por exemplo, em vez de usar
você simplesmente usa
Espero que tenha ajudado alguém.
ATUALIZAR:
Você poderia fazer assim agora
fonte
Você poderia fazer isso:
Ou melhor ainda:
fonte
você pode usar a seguinte extensão e eu acho que é muito bom:
E é usado assim:
fonte
Eu escreveria seu próprio método no tipo PropertyA (ou um método de extensão, se não for o seu tipo) usando o padrão semelhante ao tipo Nullable.
fonte
Apenas tropecei neste post.
Algum tempo atrás, fiz uma sugestão no Visual Studio Connect sobre a adição de um novo
???
operador.http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4104392-add-as-an-recursive-null-reference-check-opera
Isso exigiria algum trabalho da equipe do framework, mas não é necessário alterar a linguagem, apenas fazer a mágica do compilador. A ideia era que o compilador deveria alterar este código (sintaxe não permitida atm)
neste código
Para verificação nula, pode parecer
fonte
Eu escrevi um método que aceita um valor padrão, aqui está como usá-lo:
Aqui está o código:
fonte
Não é possível.
ObjectA.PropertyA.PropertyB
irá falhar seObjectA
for nulo devido à desreferenciação nula, o que é um erro.if(ObjectA != null && ObjectA.PropertyA
... funciona devido a curto-circuito, ou sejaObjectA.PropertyA
, nunca será verificado seObjectA
estánull
.A primeira maneira que você propõe é a melhor e mais clara com a intenção. No mínimo, você poderia tentar redesenhar sem ter que depender de tantos nulos.
fonte
Essa abordagem é bastante direta, uma vez que você supera o lambda gobbly-gook:
Com uso que pode ser semelhante a:
fonte
O
??
(operador de coalescência nula) significa que se o primeiro argumento fornull
, retorne o segundo em vez disso.fonte