Pergunta

Eu não quero dizer fundição dinâmica no sentido de lançar uma interface inferior ou classe base para uma classe mais derivada, quero dizer tomar uma definição de interface que criei, e em seguida, dinamicamente lançando a essa interface um objeto diferente NÃO derivada dessa interface, mas apoiando todas as chamadas.

Por exemplo,

interface IMyInterface
{
   bool Visible
   {
      get;
   }
}

TextBox myTextBox = new TextBox();
IMyInterface i = (dynamic<IMyInterface>)myTextBox;

Isto poderia ser alcançado em tempo de compilação para tipos conhecidos, e tempo de execução para instâncias declarado com dinâmica. A definição de interface é conhecido, como é o tipo (neste exemplo) para que o compilador pode determinar se o objeto suporta as chamadas definidos pela interface e realizar um pouco de magia para nós ter o elenco.

Meu palpite é que isso não é suportado em C # 4 (eu era incapaz de encontrar uma referência a ele), mas eu gostaria de saber com certeza. E se não for, eu gostaria de discutir se ele deve ser incluído em uma variante futuro da língua ou não, e as razões a favor e contra. Para mim, isso parece ser uma boa adição para permitir maior polimorfismo no código sem ter que criar novos tipos inteiros para embrulhar tipos quadro existente.

Atualizar
Para que alguém me acusar de plágio, eu não estava ciente de Jon Skeet tendo já propôs esta . No entanto, bom saber que nós pensamos da sintaxe extremamente semelhante, o que sugere que pode ser intuitivo, pelo menos. Enquanto isso, "tem uma idéia original" permanece na minha lista de balde para outro dia.

Foi útil?

Solução

Eu acho que Jon Skeet tem tido uma tal proposta ( http://msmvps.com/blogs/jon_skeet/archive/2008/10/30/c-4-0-dynamic-lt-t-gt.aspx ), mas, até agora, eu não ouvi esse C # 4.0 vai tê-lo.

Outras dicas

Eu acho que é problemático. Você está introduzindo o acoplamento entre duas classes que não estão acopladas.

Considere o seguinte código.

public interface IFoo
{
   int MethodA();
   int MethodB();
}

public class Bar
{
   int MethodA();
   int MethodB();
}

public class SomeClass
{
   int MethodFoo(IFoo someFoo);
}

isso deve, então, ser legal?

int blah = someClass.MethodFoo((dynamic<IFoo>)bar);

parece como deve ser legal, porque o compilador deve ser capaz de tipo dinamicamente bar como algo que implementa IFoo.

No entanto, neste ponto você está acoplando IFoo e Bar através de uma chamada em uma parte completamente separado do seu código.

Se você editar Bar porque já não precisa MethodB, de repente someClass.MethodFood não funciona mais, apesar de Bar e IFoo não são relacionados.

Da mesma forma, se você adicionar Modo C () para IFoo, seu código iria quebrar de novo, mesmo que IFoo e Bar ostensivamente não estão relacionados.

O fato é que, embora isso seria útil em casos selecionados onde há semelhanças entre os objetos que você não controla, há uma razão que as interfaces têm de ser explicitamente ligada a objetos, ea razão é para que o compilador pode garantia de que o objeto implementa-lo.

Não há necessidade de C # para apoiar isso, pois pode ser implementada muito limpa como biblioteca.

Eu vi três ou quatro implementações separadas (eu comecei a escrever um para mim antes que eu encontrei-los). Aqui é o tratamento mais completo que eu já vi:

http://bartdesmet.net/blogs/bart/archive/2008/11/10/introducing-the-c-ducktaper-bridging-the-dynamic-world-with-the -static-world.aspx

Provavelmente vai ser ainda mais fácil de implementar uma vez que o DLR está integrado no tempo de execução.

Como o wrapper / despachante de classe para uma determinada interface pode ser gerado uma vez e depois armazenada em cache, e depois um determinado objeto de tipo desconhecido pode ser enrolado uma vez, há muito espaço para armazenamento em cache de sites de chamada, etc. assim que o desempenho deve ser excelente.

Em contraste, eu acho que a palavra-chave dynamic, que é um recurso de linguagem, e um enorme complexo, é uma digressão desnecessária e potencialmente desastroso, em uma linguagem que anteriormente tinha uma filosofia tipagem estática muito clara, que deu chifres-shoe -lhe uma direção óbvia para melhorias futuras. Eles devem ter ficado com isso e fez o trabalho de inferência tipo melhor e melhor até digitação se tornou mais invisível. Existem tantas áreas onde eles poderiam evoluir a língua, sem quebrar os programas existentes, e ainda assim não o fizerem, simplesmente devido a limitações de recursos (por exemplo, o var razão não pode ser usado em mais lugares é porque eles teriam que reescrever o compilador e eles não têm tempo).

Eles ainda estão fazendo coisas boas em C # 4.0 (as características de variância), mas há muito mais que poderia ser a ser feito para tornar o sistema de tipo mais inteligente, mais automático, mais poderosa na detecção de problemas em tempo de compilação. Em vez disso, estamos ficando essencialmente um chamariz.

O quadro opensource Impromptu-Interface faz isso usando o C # 4 e o DLR .

using ImpromptuInterface;

interface IMyInterface
{
   bool Visible
   {
      get;
   }
}

TextBox myTextBox = new TextBox();
IMyInterface i = myTextBox.ActLike<IMyInterface>();

Uma vez que ele usa o DLR que também irá trabalhar com ExpandoObject e DynamicObject.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top