Então escrevemos:
Customer c = new Customer();
Por que o design não é tal que escrevemos:
c = new Customer();
c.CreditLimit = 1000;
O compilador pode calcular pontos c para um cliente e permitir que os membros do cliente sejam chamados em c?
Eu sei que podemos escrever:
IPerson c = new Customer();
IPerson e = new Employee();
para poder escrever:
public string GetName(IPerson object)
{
return object.Name
}
string name = GetName(c); // or GetName(e);
Mas se escrevêssemos:
c = new Customer();
e = new Employee();
ainda poderíamos escrever:
public string GetName(object)
{
return object.Name
}
string name = GetName(c); // or GetName(e);
O compilador pode reclamar do código imediatamente acima se o tipo de objeto c referenciado não suportar uma propriedade Name (pois pode verificar quais membros são usados no argumento / parâmetro dentro do método) ou o tempo de execução pode reclamar.
Mesmo com a palavra-chave dinâmica do C #, ainda estamos usando uma variável 'type' (determinada em tempo de execução). Mas por que uma variável precisa de um tipo? Estou certo de que deve haver uma boa razão, mas não consigo pensar nisso!
var
em C # e ser informado sobre onde deseja declarar que uma variável é sempre boa.Respostas:
fonte
a = new Bar()
e depois chama um método da classeBaz
), o compilador gera um erro. Idiomas como Haskell e OCaml foram pioneiros na inferência de tipo, mas está presente em C #, com avar
palavra - chave.Você tem um ponto perfeitamente válido, os idiomas que não controlam o tipo de uma variável existem e são chamados de "tipo dinâmico". A categoria inclui idiomas como JavaScript, Perl, Lisp e Python.
A vantagem que obtemos de uma linguagem de tipo estaticamente é uma verificação adicional de erros em tempo de compilação.
Suponha, por exemplo, que você tenha o seguinte método:
Seria possível, se você tiver um cliente
bob
e um funcionáriojames
em seu código, ligar por enganoaddCustomerContact(james, bob)
, o que é inválido. Mas se o compilador não souber os tipos das variáveis, não será possível avisá-lo de que você fez uma chamada inválida. Em vez disso, ocorrerá um erro no tempo de execução ... e como os idiomas de tipo dinâmico não verificam o tipo de parâmetros transmitidos aos métodos, esse problema ocorre sempre que seu código tenta usar propriedades dojames
objeto somente para clientes ou propriedades somente para funcionários dobob
objeto. Isso pode demorar muito depois que o par (james, bob) foi adicionado à lista de contatos do cliente.Agora, você pode se perguntar, por que não pode o compilador ainda inferir o tipo de
james
ebob
, e ainda nos avisar? Às vezes, isso é possível, mas se as variáveis realmente não tiverem tipo, poderíamos fazer o seguinte:É perfeitamente legal atribuir qualquer valor a qualquer variável, pois dissemos que as variáveis não têm tipo. Isso também significa que nem sempre podemos saber o tipo de uma variável, porque ela pode ser de tipos diferentes, com base em diferentes caminhos de execução.
Em geral, linguagens de tipo dinâmico são usadas para linguagens de script, onde não há etapa de compilação e, portanto, não existem erros de compilação, o que significa que as teclas extras necessárias para fornecer o tipo de variáveis não seriam muito úteis.
Também existem algumas vantagens distintas em linguagens dinamicamente tipadas, principalmente em termos de menos código para implementar o mesmo design: as interfaces não precisam ser escritas, porque tudo é "tipificado" (nós apenas nos importamos com os métodos / propriedades que um objeto possui , e não a qual classe o objeto pertence), as variáveis não precisam receber um tipo explícito ... com a troca que descobrimos sobre um pouco menos de bugs antes de começarmos a executar nosso código.
fonte
Portanto, programadores profissionais não precisam descobrir se
O que é um erro, em tempo de compilação com uma linguagem digitada estaticamente ou em tempo de execução com uma linguagem digitada dinamicamente. Bem são, de qualquer maneira.
fonte
Supondo que você tinha uma variável
one
(definida como 1) e tentou avaliarone + one
. Se você não tinha idéia do tipo, 1 + 1 será ambíguo. Você pode argumentar que 2 ou 11 podem ser respostas corretas. Torna-se ambíguo se o contexto não for fornecido.Eu já vi isso acontecer no SQLite, onde os tipos de bancos de dados foram inadvertidamente definidos em
VARCHAR
vez deINT
e quando as operações foram concluídas, as pessoas estavam obtendo resultados inesperados.Em c #, se o contexto inferir um tipo, você pode usar a
var
palavra - chave.Compilará c e e com os tipos inferidos em tempo de compilação.
fonte
1 + 1
sempre tem o tipoint
, mas não há necessidade de declarar isso. A questão é por que as variáveis têm um tipo, não valores .variables
não viuvalues
quando eu usei1 + 1
no meu exemplo. Eu acho que não estava claro.one=1; print(one+one)
imprime2
.one="1"; print(one+one)
impressões11
. O exemplo do SQLite é mais convincente, mas o problema é de digitação fraca, por isso não é realmente relevante para C #.ORDER BY
inadvertidamente feito em umVARCHAR
campo. Consulte stackoverflow.com/questions/9103313/… .Uma variável não precisa ter um tipo associado. Os idiomas em que isso é verdade incluem Lisp, Scheme, Erlang, Prolog, Smalltalk, Perl, Python, Ruby e outros.
Também é possível que uma variável tenha um tipo, mas talvez você não precise escrever o tipo no programa. Isso geralmente é chamado de inferência de tipo. ML, Haskell e seus descendentes têm uma inferência poderosa de tipo; algumas outras linguagens o possuem em formas menores, como as
auto
declarações de C ++ .O principal argumento contra a inferência de tipo é que ela prejudica a legibilidade. Geralmente é mais fácil entender o código quando os tipos são escritos.
fonte
Quando você identifica o tipo que sua variável representa, está fazendo uma declaração sobre algumas coisas. Você está identificando os requisitos de alocação de memória para sua variável e definindo regras de compatibilidade e intervalo para sua variável. Ele fornece uma maneira de evitar confusões sobre suas intenções com relação aos dados que você está armazenando e fornecer um meio relativamente barato para identificar possíveis problemas em seu código em tempo de compilação.
Se você declarar as seguintes variáveis:
O que você pode deduzir sobre essas variáveis? É
myVar
assinado ou não assinado? É de 8 bits, 64 bits ou algo assim? ÉmyOtherVar
uma String (efetivamente uma matriz) ou um Char? É ANSI ou Unicode?Ao fornecer tipos de dados específicos, você fornece ao compilador pistas sobre como ele pode otimizar os requisitos de memória para seu aplicativo. Alguns idiomas não se preocupam muito com esse tipo de coisa, permitindo que esses assuntos sejam tratados em tempo de execução, enquanto outros idiomas permitem uma certa quantidade de digitação dinâmica, porque, analisando o código, os tipos de dados podem ser inferidos.
Outro ponto com linguagens fortemente tipadas é que ele evita a necessidade de fornecer instruções ao compilador toda vez que você usa uma variável. Você pode imaginar o quão horrível e ilegível seu código se tornaria se toda vez que você acessasse uma variável, você fosse forçado a convertê-lo efetivamente para informar ao compilador que tipo de valor era? !!
fonte
Um programa de computador é um gráfico de nós do processo que descreve o que uma "máquina", representada pelo tempo de execução do idioma (estendido com kits de ferramentas na maioria dos casos) deve fazer, em que ordem ou sob quais condições. Este gráfico é representado por um arquivo de texto (ou vários arquivos de texto) escrito em um idioma específico e (parcial ou totalmente) criado quando o compilador / intérprete lê (desserializa) esse arquivo. Além disso, existem alguns ambientes (UML ou ferramentas de geração de programas gráficos) em que você pode criar esse gráfico e gerar o código-fonte em um idioma de destino.
Por que eu digo isso? Porque isso leva à resposta à sua pergunta.
O texto do programa é suas instruções sobre como o computador deve resolver a tarefa real, contendo as etapas do processo (condições, ações) E a estrutura (quais componentes você usa na solução). O último significa que você obtém ou cria algumas instâncias de outros componentes, as coloca em caixas nomeadas (variáveis) e as utiliza: acesse seus dados e serviços.
Alguns idiomas oferecem caixas uniformes, nas quais apenas o rótulo é importante, mas você pode colocar qualquer coisa nelas, você pode até usar uma variável chamada "target" para armazenar uma "Person" no início e "Car" no final de o mesmo algoritmo. Outros exigem que você crie caixas "em forma", portanto caixas diferentes para uma Pessoa ou um Carro - embora elas ainda permitam que você crie uma "caixa genérica" (Objeto Java, C / C ++ void *, "Objective C" id "...) e jogue como quiser. As linguagens digitadas permitem que você expresse sua estrutura com mais detalhes, criando "contratos de tipo" para suas variáveis (embora você possa burlar essa limitação), enquanto as linguagens não tipificadas suportam a abordagem "certamente saberei o que coloquei nessa caixa dessa vez" como o padrão e único comportamento.
Ambas as abordagens são viáveis, possuem inteligência de compilador, muitos livros de programação, práticas e estruturas escritas usando-as (e outras toneladas de livros sobre essas estruturas) em diferentes níveis. Portanto, hoje a resposta parece ser mais uma questão de gosto e conhecimento da equipe real do programador do que uma declaração adequadamente fundamentada, medida e verificada sobre o uso ou não de tipos.
É desnecessário dizer que prefiro regras a truques, especialmente para projetos de longo prazo em grandes equipes (também conhecidos como "sérios"). Razão: até onde eu sei, as causas mais prováveis de falha / escorregamento do projeto de SW são: requisitos pouco claros e design deficiente (80%! Por um estudo que conheço), e apenas uma porcentagem permanece para a codificação real. Todas as regras e contratos impõem um design mais limpo, pensando no futuro, e exigem que as decisões sejam tomadas mais cedo e pelas pessoas apropriadas. Tipos significam regras: menos "liberdade" e "frieza" - mais preparação, pensamento, padrões de codificação, trabalho em equipe controlado. Para mim, isso parece um fator necessário para o sucesso, e também "lar, doce lar".
Meus 2 centavos.
fonte
AFIAK todos os idiomas com digitação dinâmica são idiomas interpretados. Isso já é muito ineficiente, adicionar a ineficiência da digitação dinâmica não será uma grande perda de tempo. Uma linguagem compilada, no entanto, não estará se referindo a coisas pelo nome quando estiver em execução. (Exceto o uso ocasional de reflexão .net ou similares - recursos muito lentos em comparação com o idioma subjacente.) A busca por todos esses nomes será lenta, lenta, lenta.
fonte
As linguagens de tipo dinâmico são frequentemente apresentadas como "orientadas a objetos". Eles não são. Eles podem ser orientados a encapsulamento, mas nunca orientados a objetos. A orientação a objetos tem tudo a ver com tipos.
"O garoto anda de bicicleta do irmão até o supermercado e compra um pedaço de pão na mercearia". Usando a orientação a objetos, é possível escrever imediatamente um conjunto de classes (tipos) para descrever esse cenário do mundo real.
Em uma linguagem de tipo dinâmico, o cenário só pode ser representado da seguinte maneira:
"O objeto monta o objeto do objeto até o objeto e compra um objeto do objeto".
O poder da orientação a objetos está em sua capacidade de modelar o mundo em termos naturais, de modo que o desenvolvedor de software possa usar os dois lados do cérebro para escrever software e resolver problemas mais como um ser humano, menos como um programador de computador. Esse poder está ausente em idiomas de tipo dinâmico.
A digitação estática permite melhor eficiência de codificação, reutilização e manutenção, porque os ambientes de desenvolvimento integrados conhecem os tipos de variáveis. Conhecendo os tipos de variáveis, um IDE pode fornecer o preenchimento automático para que o programador não precise se referir novamente à definição da classe para lembrar se a propriedade do membro foi digitada "backlightControl" ou "backLightControl" ou "bkLightCtrl".
A digitação estática permite refatoração automatizada, porque o IDE conhece todos os lugares em que uma variável contém uma instância do objeto que está sendo refatorado.
A digitação estática permite maior reutilização e manutenção. A digitação dinâmica é melhor para código descartável. Suponha que um novo desenvolvedor saia da rua e analise um pedaço de código existente. Se o código for digitado estaticamente, o desenvolvedor poderá, com dois cliques do mouse, examinar a definição de classe de cada uma das variáveis envolvidas, saber para que serve a classe, saber para que outros métodos e propriedades estão disponíveis. Se o código for digitado dinamicamente, o desenvolvedor precisará usar a pesquisa global para descobrir o que está acontecendo.
fonte
Boy
aula, mas duvido que possa fazer tudo o que um "garoto" do mundo real faz. No entanto, no seu exemplo dinâmico (O objeto monta ...), sabemos a única coisa importante sobre esse objeto "menino" - ele pode montar . Essa é a filosofia básica das linguagens de tipo dinâmico. Tem + ve se-ve. Qual você gosta é a sua opinião.