Em javascript, você pode detectar se uma propriedade é definida usando a palavra-chave indefinida:
if( typeof data.myProperty == "undefined" ) ...
Como você faria isso em C # usando a palavra-chave dinâmica com ExpandoObject
e sem gerar uma exceção?
c#
dynamic
expandoobject
Softlion
fonte
fonte
data.myProperty
; verifica o quetypeof data.myProperty
retorna. É correto quedata.myProperty
possa existir e estar definido comoundefined
, mas nesse caso,typeof
retornará algo diferente"undefined"
. Portanto, esse código funciona.Respostas:
De acordo com o MSDN, a declaração mostra que está implementando o IDictionary:
Você pode usar isso para ver se um membro está definido:
fonte
Uma distinção importante precisa ser feita aqui.
A maioria das respostas aqui são específicas para o ExpandoObject, mencionado na pergunta. Mas um uso comum (e um motivo para abordar essa questão ao pesquisar) é ao usar o ASP.Net MVC ViewBag. Essa é uma implementação / subclasse personalizada do DynamicObject, que não gera uma exceção quando você verifica nulo em qualquer nome de propriedade arbitrária. Suponha que você possa declarar uma propriedade como:
Suponha que você queira verificar seu valor e se está definido - se ele existe. O seguinte é válido, será compilado, não emitirá nenhuma exceção e fornece a resposta certa:
Agora livre-se da declaração de EnableThinger. O mesmo código compila e executa corretamente. Não há necessidade de reflexão.
Ao contrário do ViewBag, o ExpandoObject será lançado se você verificar nulo em uma propriedade que não existe. Para tirar a funcionalidade mais suave do MVC ViewBag de seus
dynamic
objetos, você precisará usar uma implementação de dinâmica que não seja lançada.Você pode simplesmente usar a implementação exata no MVC ViewBag:
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/DynamicViewDataDictionary.cs
Você pode vê-lo vinculado às visualizações do MVC aqui, no MVC ViewPage:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ViewPage.cs
A chave do comportamento gracioso do DynamicViewDataDictionary é a implementação do Dictionary no ViewDataDictionary, aqui:
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/ViewDataDictionary.cs
Em outras palavras, ele sempre retorna um valor para todas as chaves, independentemente do que está nele - ele simplesmente retorna nulo quando não existe nada. Porém, o ViewDataDictionary tem o ônus de estar vinculado ao modelo do MVC, portanto, é melhor remover apenas as partes graciosas do dicionário para uso fora das visualizações do MVC.
É muito longo para realmente postar todos os detalhes aqui - a maioria implementando apenas o IDictionary - mas aqui está um objeto dinâmico (classe
DDict
) que não gera verificações nulas nas propriedades que não foram declaradas no Github:https://github.com/b9chris/GracefulDynamicDictionary
Se você quiser apenas adicioná-lo ao seu projeto via NuGet, o nome dele é GracefulDynamicDictionary .
fonte
Respondi a uma pergunta muito semelhante recentemente: como reflito sobre os membros do objeto dinâmico?
Em breve, ExpandoObject não é o único objeto dinâmico que você pode obter. O Reflection funcionaria para tipos estáticos (tipos que não implementam IDynamicMetaObjectProvider). Para tipos que implementam essa interface, a reflexão é basicamente inútil. Para ExpandoObject, você pode simplesmente verificar se a propriedade está definida como uma chave no dicionário subjacente. Para outras implementações, pode ser desafiador e, às vezes, a única maneira é trabalhar com exceções. Para detalhes, siga o link acima.
fonte
ATUALIZADO: você pode usar delegados e tentar obter um valor da propriedade do objeto dinâmico, se existir. Se não houver propriedade, simplesmente pegue a exceção e retorne false.
Dê uma olhada, ele funciona bem para mim:
A saída do código é a seguinte:
fonte
IsPropertyExist
. Neste exemplo, você sabe que é possível lançar umInvalidOperationException
. Na prática, você não tem idéia de que exceção pode ser lançada. +1 para neutralizar o culto à carga.Eu queria criar um método de extensão para poder fazer algo como:
... mas você não pode criar extensões de
ExpandoObject
acordo com a documentação do C # 5 (mais informações aqui ).Então acabei criando um auxiliar de classe:
Para usá-lo:
fonte
Por que você não deseja usar o Reflection para obter um conjunto de tipos properyes? Como isso
fonte
Esse método de extensão verifica a existência de uma propriedade e, em seguida, retorna o valor ou nulo. Isso é útil se você não deseja que seus aplicativos gerem exceções desnecessárias, pelo menos as que você pode ajudar.
Se pode ser usado como tal:
ou se sua variável local for 'dinâmica', será necessário convertê-la no ExpandoObject primeiro.
fonte
Dependendo do seu caso de uso, se nulo puder ser considerado o mesmo que indefinido, você poderá transformar seu ExpandoObject em um DynamicJsonObject.
Resultado:
fonte
fonte
Ei, parem de usar o Reflection para tudo o que custa muitos ciclos de CPU.
Aqui está a solução:
fonte
Tente este
fonte
dynamic
objetos (sempre retornanull
).