Deficiências do uso de tipos dinâmicos em C #


14

Estive recentemente estudando mais sobre os tipos dinâmicos em c #. Com alguns exemplos que entendi quando o código é compilado, ele não precisa ser recompilado novamente, mas pode ser executado diretamente.

Sinto que a flexibilidade fornecida pela palavra-chave para realmente alterar o tipo de dados à vontade é uma grande vantagem .

Questão,

Existem deficiências específicas, além das chamadas de método dinâmico erradas, que lançam exceções de tempo de execução que os desenvolvedores devem conhecer antes de iniciar a implementação.


3
No C # 3, sempre considerei o uso de objectou conversão direta do tipo um cheiro de código. Em quase todos os casos, isso significava que eu ou um membro da nossa equipe não havia projetado uma interface apropriada para essa funcionalidade. Eu estou supondo que, se eu estivesse usando o C # 4 agora, também me sentiria da mesma maneira sobre o uso do dynamic. Eu poderia ver o caso, se você tornar tudo dinâmico, mas nesse caso você também pode ter selecionado um idioma de tipo dinâmico. * 8 ')
Mark Booth

@ MarkBooth +1 para a perspectiva. É então seguro dizer que a implementação do núcleo usando C # ainda vai permanecer fortemente tipado in-apesar da introdução de tipos dinâmicos em 4.0
Karthik Sreenivasan

Usar dynamicem C # significa que você não precisa abandonar o IronPython se tudo o que você precisa é de digitação dinâmica para uma pequena parte do seu código. Para um avaliador de expressão, tive grande sucesso usando dynamicpara representar os operandos de uma expressão e os resultados da avaliação.
Ed James

@ EdJames - Isso soa como um ótimo uso dynamic, além disso, eu gostaria de saber sobre o IronPython quando estava desenvolvendo com o .Net - isso poderia ter tornado muito mais fácil certas coisas que estávamos tentando fazer .
21712 Mark Booth

Respostas:


16

A principal falha é que você joga fora uma das principais propriedades (não necessariamente vantagens) do C # - que é estaticamente tipada (e na maior parte do tipo é segura).

O problema com a digitação dinâmica é que muitas vezes oculta erros que seriam revelados durante a compilação. Esse bug se manifesta apenas no tempo de execução, o que, obviamente, dificulta a detecção.

Existem muito poucas razões para usar a digitação dinâmica em C # da IMO, a principal delas é a colaboração com linguagens de tipo dinâmico (que é AFAIK, a razão pela qual a dinâmica foi introduzida em primeiro lugar).

Se você deseja fazer uma programação totalmente dinâmica, digite alguma linguagem projetada para ser dinâmica, e não faça com que o C # seja dinâmico. Você pode usar, por exemplo, o IronPython, se quiser usar as bibliotecas .Net


+1 para o IronPython. Isso significa que isso pode levar a problemas de manutenção a longo prazo.
Karthik Sreenivasan

6
A grande coisa que dynamiclhe dá é a capacidade de converter um objeto para o seu tipo real sem nenhum tipo de invasão de reflexão. Por exemplo, se Base foo = new Derived();e havia dois métodos sobrecarregados Moo(Base x)e Moo(Derived x), em seguida , Moo(foo)chama Moo(Base x), mas Moo((dynamic)foo)chama Moo(Derived x). Isso leva a uma implementação muito elegante do padrão Visitor, por exemplo: code.logos.com/blog/2010/03/… e, em geral, é uma técnica muito poderosa.

@TheMouthofaCow Bom, certamente existem alguns outros usos "legítimos" para a dinâmica também; no entanto, esses são poucos e distantes (e você definitivamente precisa saber o que está fazendo antes de tentar algo assim).
Matěj Zábský

@TheMouthofaCow Um padrão de design relativamente novo (O Padrão do Visitante) a ser observado. Obrigado.
Karthik Sreenivasan

1
Sim, é bem legal. Eu o criei de forma independente na semana passada, então foi bom ver que é uma ideia aceita que foi adotada no arsenal de C #.

9

Não tenho certeza de que tipo de deficiências você está procurando, mas se quiser saber sobre os recursos que funcionam com a digitação estática, mas não com dynamic, existem alguns:

  1. Métodos de extensões não funcionam. Este é provavelmente o maior. Se você tiver dynamic collection, não poderá usar código como collection.Distinct(). Isso ocorre porque os métodos de extensão disponíveis dependem do espaço para nomeusing o DLR não tem como conhecê-los.

    Como solução alternativa, você pode chamar o método como se fosse método estático normal: Enumerable.Distinct(collection). Ou você pode alterar o tipo da coleção para algo como IEnumerable<dynamic>.

  2. foreachrequer IEnumerable. Em C # normal, foreaché baseado em padrões. Ou seja, não requer nenhuma interface específica, apenas um GetEnumerator()método que retorna um objeto adequado. Se você usar foreachem dynamic, a implementação de IEnumerableé necessário. Mas como o motivo desse comportamento é que o C # 1.0 não tinha genéricos, essa "falha" é praticamente irrelevante.


+1 para o método de extensões. Isso também se aplica a outros operadores de consulta LINQ como GroupBy ()?
Karthik Sreenivasan

2
@Karthik: Sim, sim. Eu acho que os métodos de extensão são açúcar sintático em tempo de compilação, daí o fato de que eles não são resolvidos.

@TheMouthofaCow +1 - Obrigado pelo esclarecimento.
Karthik Sreenivasan

1
Concordo com os métodos de extensão, ou seja, como a dinâmica não pode descobrir métodos de extensão em tempo de execução, mas não pude seguir a coleção dinâmica que você explicou.
Karthik Sreenivasan

7

O problema com os tipos dinâmicos (não variáveis ​​declaradas como dinâmicas) no .net é que eles não têm muita funcionalidade disponível para os tipos estáticos.

  • não há reflexão (você pode interagir com os membros, mas não muito mais)
  • sem metadados (a validação é feita nos sites de dados dinâmicos / mvc)
  • absolutamente nenhuma verificação no tempo de compilação (nenhum erro de ortografia será detectado)
  • já que esse é um recurso poderoso, os noobs tendem a abusar / abusar / interpretar mal
  • código escrito com tipos dinâmicos tende a ser difícil de manter e muito difícil de refatorar
  • por causa da digitação do pato e outros recursos, os gurus podem escrever um código ilegível para qualquer outra pessoa

Portanto, não escreva código com tipos dinâmicos, a menos que você saiba o que está fazendo.


6

Uma vez que dynamicé apenas uma marcaobject ele tipos de valor.

Isso pode ter implicações no desempenho, mas como eu usaria a digitação estática no código crítico de desempenho, isso provavelmente não é um problema na prática.

Esse boxe também interfere nos tipos de valores mutáveis. Se você modificá-los com dynamic, modifique apenas a cópia em caixa. Mas como você não deve usar tipos de valores mutáveis ​​em primeiro lugar, isso também não é um grande problema.


+1 Eu definitivamente concordo. A digitação estática seria a melhor abordagem para o código crítico de desempenho.
Karthik Sreenivasan
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.