Quais são as diferenças entre System.Dynamic.ExpandoObject
,System.Dynamic.DynamicObject
e dynamic
?
Em quais situações você usa esses tipos?
Quais são as diferenças entre System.Dynamic.ExpandoObject
,System.Dynamic.DynamicObject
e dynamic
?
Em quais situações você usa esses tipos?
A dynamic
palavra-chave é usada para declarar variáveis que devem ser atrasadas.
Se você deseja usar a ligação tardia, para qualquer tipo real ou imaginário, use odynamic
palavra chave e o compilador fará o resto.
Quando você usa a dynamic
palavra-chave para interagir com uma instância normal, o DLR executa chamadas com ligação tardia aos métodos normais da instância.
A IDynamicMetaObjectProvider
interface permite que uma classe assuma o controle de seu comportamento de ligação tardia.
Quando você usa a dynamic
palavra-chave para interagir com uma IDynamicMetaObjectProvider
implementação, o DLR chama os IDynamicMetaObjectProvider
métodos e o próprio objeto decide o que fazer.
As classes ExpandoObject
e DynamicObject
são implementações de IDynamicMetaObjectProvider
.
ExpandoObject
é uma classe simples que permite adicionar membros a uma instância e usá-los como dynamic
aliados.
DynamicObject
é uma implementação mais avançada que pode ser herdada para fornecer facilmente um comportamento personalizado.
Tentarei fornecer uma resposta mais clara a essa pergunta, para explicar claramente quais são as diferenças entre dinâmico
ExpandoObject
eDynamicObject
.Muito rapidamente,
dynamic
é uma palavra-chave. Não é um tipo per se. É uma palavra-chave que instrui o compilador a ignorar a verificação de tipo estático no tempo de design e, em vez disso, usar a ligação tardia no tempo de execução. Portanto, não vamos gastar muito tempodynamic
restante desta resposta.ExpandoObject
eDynamicObject
são de fato tipos. Na SUPERFÍCIE, eles se parecem muito. Ambas as classes são implementadasIDynamicMetaObjectProvider
. No entanto, se aprofundar e você verá que eles não são semelhantes.O DynamicObject é uma implementação parcial do
IDynamicMetaObjectProvider
objetivo puramente de ser o ponto de partida para os desenvolvedores implementarem seus próprios tipos personalizados que suportam o envio dinâmico com comportamento de recuperação e armazenamento subjacente personalizado para fazer o envio dinâmico funcionar.Em resumo, use DynamicObject quando desejar criar seus próprios tipos que podem ser usados com o DLR e trabalhar com qualquer comportamento PERSONALIZADO que você desejar.
Exemplo: imagine que você gostaria de ter um tipo dinâmico que retorne um padrão personalizado sempre que uma tentativa de obtenção de um membro que NÃO existe (ou seja, não foi adicionada em tempo de execução). E esse padrão dirá: "Sinto muito, não há cookies neste frasco!". Se você deseja um objeto dinâmico que se comporte dessa maneira, precisará controlar o que acontece quando um campo não é encontrado. ExpandoObject não permitirá que você faça isso. Portanto, você precisará criar seu próprio tipo com um comportamento exclusivo de resolução dinâmica de despacho (despacho) e usá-lo em vez do software pronto
ExpandoObject
.Você pode criar um tipo da seguinte maneira: (Observe que o código abaixo é apenas ilustrativo e pode não ser executado. Para saber como usar o DynamicObject corretamente, existem muitos artigos e tutoriais em outros lugares.)
Agora, poderíamos usar essa classe imaginária que acabamos de criar como um tipo dinâmico que possui um comportamento muito personalizado se o campo não existir.
ExpandoObject
é uma implementação COMPLETA deIDynamicMetaObjectProvider
, onde a equipe do .NET Framework tomou todas essas decisões por você. Isso é útil se você não precisar de nenhum comportamento personalizado e acha que o ExpandoObject funciona bem o suficiente para você (90% do tempo,ExpandoObject
é bom o suficiente). Por exemplo, veja o seguinte e, para o ExpandoObject, os designers optaram por lançar uma exceção se o membro dinâmico não existir.Então, para resumir,
ExpandoObject
é simplesmente uma maneira pré-escolhida de estender o DynamicObject com certos comportamentos de despacho dinâmico que provavelmente funcionarão para você , mas podem não depender de suas necessidades particulares.Considerando que,
DyanmicObject
é um BaseType auxiliar que simplifica e facilita a implementação de seus próprios tipos com comportamentos dinâmicos exclusivos.Um tutorial útil no qual grande parte da fonte de exemplo acima é baseada.
fonte
DynamicObject
: ao substituirTryGetMember
, se você retornar falso, aRuntimeBinderException
será lançada ao tentar acessar a propriedade não existente. Para que o snippet funcione, você deve retornartrue
.De acordo com a especificação da linguagem C #,
dynamic
é uma declaração de tipo. Ou seja,dynamic x
significa que a variávelx
tem o tipodynamic
.DynamicObject
é um tipo que facilita a implementaçãoIDynamicMetaObjectProvider
e, portanto, substitui o comportamento de ligação específico para o tipo.ExpandoObject
é um tipo que age como uma bolsa de propriedade. Ou seja, você pode adicionar propriedades, métodos e assim por diante a instâncias dinâmicas desse tipo em tempo de execução.fonte
dynamic
não é um tipo real ... é apenas uma dica para dizer ao compilador para usar a ligação tardia para essa variável.dynamic
variáveis são realmente declarado comoobject
em MSILO exemplo acima
DynamicObject
não indica claramente a diferença, porque está basicamente implementando a funcionalidade que já é fornecida peloExpandoObject
.Nos dois links mencionados abaixo, é muito claro que, com a ajuda de
DynamicObject
, é possível preservar / alterar o tipo real (XElement
no exemplo usado nos links abaixo) e melhor controle sobre propriedades e métodos.https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject/
https://blogs.msdn.microsoft.com/csharpfaq/2009/10/19/dynamic-in-c-4-0-creating-wrappers-with-dynamicobject/
fonte