É possível encurtar de alguma forma esta afirmação?
if (obj != null)
obj.SomeMethod();
porque escrevo muito isso e fica muito chato. A única coisa que posso pensar é implementar o padrão Null Object , mas isso não é o que posso fazer todas as vezes e certamente não é uma solução para encurtar a sintaxe.
E problema semelhante com eventos, onde
public event Func<string> MyEvent;
e então invocar
if (MyEvent != null)
MyEvent.Invoke();
Respostas:
Do C # 6 em diante, você pode apenas usar:
ou:
O
?.
é o operador de propagação nula e causará um.Invoke()
curto-circuito quando o operando fornull
. O operando é acessado apenas uma vez, não havendo risco do problema de "mudança de valor entre checar e invocar".===
Antes do C # 6, não: não há mágica de segurança nula, com uma exceção; métodos de extensão - por exemplo:
agora isso é válido:
No caso de eventos, tem a vantagem de remover também a condição de corrida, ou seja, você não precisa de uma variável temporária. Normalmente, você precisa de:
mas com:
podemos usar simplesmente:
fonte
?.
- em VB14 e superiorO que você está procurando é o Null condicional (e não "coalescência") operador:
?.
. Ele está disponível a partir de C # 6.Seu exemplo seria
obj?.SomeMethod();
. Se obj for nulo, nada acontece. Quando o método tem argumentos, por exemplo,obj?.SomeMethod(new Foo(), GetBar());
os argumentos não são avaliados seobj
for nulo, o que importa se a avaliação dos argumentos tiver efeitos colaterais.E o encadeamento é possível:
myObject?.Items?[0]?.DoSomething()
fonte
Um método de extensão rápido:
exemplo:
ou alternativamente:
exemplo:
fonte
Os eventos podem ser inicializados com um delegado padrão vazio que nunca é removido:
Nenhuma verificação nula necessária.
[ Atualização , obrigado a Bevan por apontar isso]
Porém, esteja ciente do possível impacto no desempenho. Um rápido micro benchmark que fiz indica que lidar com um evento sem assinantes é 2 a 3 vezes mais lento ao usar o padrão de "delegado padrão". (No meu laptop dual core de 2,5 GHz, isso significa 279 ms: 785 ms para gerar 50 milhões de eventos não inscritos.). Para pontos de acesso de aplicativos, isso pode ser um problema a ser considerado.
fonte
Sim, em C # 6.0 - https://msdn.microsoft.com/en-us/magazine/dn802602.aspx .
fonte
Este artigo de Ian Griffiths apresenta duas soluções diferentes para o problema, que ele conclui serem truques bacanas que você não deve usar.
fonte
O método de extensão cerating como o sugerido não resolve realmente problemas com condições de corrida, mas sim os esconde.
Conforme declarado, este código é o elegante equivalente à solução com variável temporária, mas ...
O problema com ambos é que é possível que o assinante do evento seja chamado DEPOIS de ter cancelado a inscrição do evento . Isso é possível porque o cancelamento da assinatura pode acontecer depois que a instância do delegado é copiada para a variável temporária (ou passada como parâmetro no método acima), mas antes que o delegado seja invocado.
Em geral, o comportamento do código do cliente é imprevisível nesse caso: o estado do componente já não podia permitir o tratamento da notificação de eventos. É possível escrever o código do cliente da maneira de lidar com isso, mas colocaria uma responsabilidade desnecessária para o cliente.
A única maneira conhecida de garantir a segurança do encadeamento é usar a instrução de bloqueio para o remetente do evento. Isso garante que todas as assinaturas \ unsubscriptions \ invocation sejam serializadas.
Para ser mais preciso, o bloqueio deve ser aplicado ao mesmo objeto de sincronização usado nos métodos de acesso adicionar / remover eventos, que é o padrão 'this'.
fonte
Concordo com a resposta de Kenny Eliasson. Vá com métodos de extensão. Aqui está uma breve visão geral dos métodos de extensão e seu método IfNotNull obrigatório.
Métodos de extensão (método IfNotNull)
fonte
Talvez não seja melhor, mas na minha opinião mais legível é criar um método de extensão
fonte
return obj == null
significa. O que isso vai retornarobj
fornull
o método retornarátrue
, eu acho.null
? Tenho certeza de que isso não funciona com os métodos do próprio tipo, então duvido que funcione com métodos de extensão também. Acredito que a melhor maneira de verificar se um objeto estánull
éobj is null
. Infelizmente, para verificar se um objeto não o é, énull
necessário colocá-lo entre parênteses, o que é uma pena.Existe um operador nulo pouco conhecido em C # para isso, ??. Pode ser útil:
http://weblogs.asp.net/scottgu/archive/2007/09/20/the-new-c-null-coalescing-operator-and-using-it-with-linq.aspx
fonte