Entonces escribimos:
Customer c = new Customer();
¿Por qué el diseño no es tal que escribimos?
c = new Customer();
c.CreditLimit = 1000;
El compilador puede calcular puntos c para un Cliente y permitir que los miembros del Cliente sean invocados en c?
Sé que podemos querer escribir:
IPerson c = new Customer();
IPerson e = new Employee();
para poder escribir:
public string GetName(IPerson object)
{
return object.Name
}
string name = GetName(c); // or GetName(e);
Pero si escribimos:
c = new Customer();
e = new Employee();
aún podríamos escribir:
public string GetName(object)
{
return object.Name
}
string name = GetName(c); // or GetName(e);
El compilador podría quejarse del código inmediatamente anterior si el tipo de objeto c referencias no admite una propiedad Nombre (ya que puede verificar qué miembros se usan en el argumento / parámetro dentro del método), o el tiempo de ejecución podría quejarse.
Incluso con la palabra clave dinámica de C #, todavía estamos usando una variable 'tipo' (determinada en tiempo de ejecución). Pero, ¿por qué una variable necesita un tipo? Estoy seguro de que debe haber una buena razón, ¡pero no puedo pensar en eso!
var
en C # y ser explícito acerca de dónde desea declarar una variable siempre es bueno.Respuestas:
fuente
a = new Bar()
y luego llama a un método de la claseBaz
), el compilador genera un error. Lenguajes como Haskell y OCaml fueron pioneros en la inferencia de tipos, pero está presente en C #, con lavar
palabra clave.Tiene un punto perfectamente válido, existen idiomas que no realizan un seguimiento del tipo de una variable y se denominan "de tipo dinámico". La categoría incluye lenguajes como JavaScript, Perl, Lisp y Python.
La ventaja que obtenemos de un lenguaje de tipo estático es una comprobación adicional de errores en tiempo de compilación.
Supongamos, por ejemplo, que tiene el siguiente método:
Sería posible, si tiene un cliente
bob
y un empleadojames
en su código, llamar por erroraddCustomerContact(james, bob)
, lo que no es válido. Pero si el compilador no conoce los tipos de variables, no puede advertirle que ha realizado una llamada no válida, en su lugar, se produce un error en tiempo de ejecución ... y dado que los lenguajes de tipo dinámico no comprueban tipo de parámetros pasados a los métodos, ese problema ocurre cada vez que su código intenta usar propiedades deljames
objeto solo para clientes o propiedades del objeto solo para empleadosbob
. Eso puede ser mucho después de que el par (james, bob) se haya agregado a la lista de contactos de clientes.Ahora, se preguntarán, ¿por qué el compilador aún no puede inferir el tipo de
james
ybob
, y todavía nos advierte? Eso a veces puede ser posible, pero si las variables realmente no tienen tipo, entonces podríamos hacer lo siguiente:Es perfectamente legal asignar cualquier valor a cualquier variable, ya que dijimos que las variables no tienen tipo. Eso también significa que no siempre podemos conocer el tipo de una variable, porque podría ser de diferentes tipos en función de diferentes rutas de ejecución.
En general, los lenguajes de tipo dinámico se utilizan para los lenguajes de secuencias de comandos, donde no hay un paso de compilación, por lo que no existen errores de compilación, lo que significa que las pulsaciones de teclas adicionales necesarias para dar el tipo de variables no serían muy útiles.
También hay algunas ventajas distintas para los lenguajes de tipo dinámico, principalmente en términos de que se necesita menos código para implementar el mismo diseño: las interfaces no necesitan estar escritas, porque todo está "tipado en pato" (solo nos importa qué métodos / propiedades tiene un objeto) , no a qué clase pertenece el objeto), no es necesario que las variables tengan un tipo explícito ... con el compromiso de que descubrimos unos pocos errores antes de comenzar a ejecutar nuestro código.
fuente
Por lo tanto, los programadores profesionales no tienen que determinar si
Lo que es un error, en tiempo de compilación con un lenguaje tipado estáticamente o en tiempo de ejecución con uno tipado dinámicamente. Bien cuerdos de todos modos.
fuente
Suponiendo que tenía una variable
one
(establecida en 1) e intentó evaluarone + one
. Si no tenía idea del tipo, entonces 1 + 1 será ambiguo. Puede argumentar que 2 u 11 podrían ser respuestas correctas. Se vuelve ambiguo si no se da contexto.He visto que esto sucede en SQLite, donde los tipos de bases de datos se configuraron inadvertidamente en
VARCHAR
lugar deINT
y cuando se realizaron operaciones, las personas obtenían resultados inesperados.En c # si el contexto infiere un tipo, puede usar la
var
palabra clave.Compilará c y e con los tipos inferidos en tiempo de compilación.
fuente
1 + 1
siempre tiene el tipoint
, pero no hay necesidad de declararlo. La pregunta es por qué las variables tienen un tipo, no valores .variables
novalues
cuando utilicé1 + 1
en mi ejemplo. Supongo que no estaba claro.one=1; print(one+one)
impresiones2
.one="1"; print(one+one)
impresiones11
. El ejemplo de SQLite es más convincente, pero el problema es uno de tipeo débil, por lo que no es realmente relevante para C #.ORDER BY
darse cuenta en unVARCHAR
campo. Ver stackoverflow.com/questions/9103313/… .Una variable no necesita tener un tipo asociado. Los idiomas en los que esto es cierto incluyen Lisp, Scheme, Erlang, Prolog, Smalltalk, Perl, Python, Ruby y otros.
También es posible que una variable tenga un tipo, pero es posible que no tenga que escribir el tipo en el programa. Esto generalmente se llama inferencia de tipos. ML, Haskell y sus descendientes tienen una poderosa inferencia de tipos; algunos otros lenguajes lo tienen en formas menores, como las
auto
declaraciones de C ++ .El argumento principal contra la inferencia de tipos es que daña la legibilidad. Por lo general, es más fácil entender el código cuando se escriben los tipos.
fuente
Cuando identifica el tipo que representa su variable, está haciendo una declaración sobre un par de cosas. Está identificando los requisitos de asignación de memoria para su variable y está definiendo las reglas de compatibilidad y rango para su variable. Proporciona una manera de evitar confusiones sobre sus intenciones para los datos que está almacenando, y para proporcionarle un medio relativamente barato para identificar posibles problemas en su código en el momento de la compilación.
Si declara las siguientes variables:
¿Qué se puede inferir acerca de estas variables? ¿Está
myVar
firmado o sin firmar? ¿Es de 8 bits, 64 bits o algo intermedio? ¿EsmyOtherVar
una cadena (efectivamente una matriz) o un Char? ¿Es ANSI o Unicode?Al proporcionar tipos de datos específicos, proporciona al compilador pistas sobre cómo puede optimizar los requisitos de memoria para su aplicación. Algunos idiomas no se molestan demasiado con este tipo de cosas, lo que permite que esos asuntos se traten en tiempo de ejecución, mientras que otros idiomas permitirán una cierta cantidad de tipeo dinámico porque al analizar el código se pueden inferir los tipos de datos.
Otro punto con los idiomas fuertemente tipados es que le ahorra la necesidad de proporcionar instrucciones al compilador cada vez que usa una variable. ¡¿Te imaginas lo horrible e ilegible que se volvería tu código si cada vez que accedieras a una variable, tuvieras que lanzarlo de manera efectiva para decirle al compilador qué tipo de valor era? !!
fuente
Un programa de computadora es un gráfico de nodos de proceso que describe lo que debe hacer una "máquina", representada por el tiempo de ejecución del lenguaje (extendido con kits de herramientas en la mayoría de los casos), en qué orden o bajo qué condiciones. Este gráfico está representado por un archivo de texto (o un montón de archivos de texto) escrito en un idioma específico y (parcial o totalmente) creado cuando el compilador / intérprete lee (deserializa) este archivo. Además, hay algunos entornos (UML o herramientas de generación de programas gráficos) en los que puede construir este gráfico y generar el código fuente en un idioma de destino.
¿Por qué digo esto? Porque esto lleva a la respuesta a tu pregunta.
El texto del programa es sus instrucciones sobre cómo la computadora debe resolver la tarea real, que contiene los pasos del proceso (condiciones, acciones) Y la estructura (qué componentes utiliza en la solución). Esto último significa que obtienes o creas algunas instancias de otros componentes, los pones en cuadros con nombre (variables) y los usas: accede a sus datos y servicios.
Algunos idiomas le dan cuadros uniformes, donde solo la etiqueta es importante, pero puede poner cualquier cosa en ellos, incluso puede usar una variable llamada "objetivo" para almacenar una "Persona" al principio y "Auto" al final de El mismo algoritmo. Otros requiere que cree cuadros "con forma", por lo tanto, diferentes para una Persona o un Coche, aunque todavía le permiten crear un "cuadro genérico" (Objeto Java, C / C ++ void *, Id. Objetivo C ...) y tíralo como quieras. Los idiomas mecanografiados le permiten expresar su estructura en detalles más finos, creando "contratos de tipo" para sus variables (aunque puede hackear esta limitación), mientras que los idiomas no tipificados apoyan este enfoque de "Seguramente sabré lo que he puesto en esa casilla esta vez". como el comportamiento predeterminado y único.
Ambos enfoques son viables, tienen su inteligencia compiladora, muchos libros de programación, prácticas y marcos escritos que los usan (y otras toneladas de libros sobre esos marcos) en diferentes niveles. Así que hoy la respuesta parece ser más una cuestión de gustos y conocimiento del equipo de programadores real que una declaración debidamente fundada, medida y verificada sobre si usar o no usar tipos.
Creo que no hace falta decir que prefiero las reglas a los trucos, especialmente para proyectos a largo plazo de grandes equipos (también conocidos como "serios"). Motivo: hasta donde yo sé, las causas más probables de un fracaso / deslizamiento de un proyecto de SW son: requisitos poco claros y diseño deficiente (80% por un estudio que conozco), y solo queda un pequeño porcentaje para la codificación real. Todas las reglas y contratos imponen un diseño más limpio, con visión de futuro y requieren que las decisiones se tomen antes y por las personas adecuadas. Los tipos significan reglas: menos "libertad" y "frescura": más preparación, pensamiento, estándares de codificación, trabajo en equipo controlado. Para mí, esto suena como un factor de éxito requerido, y también "hogar, dulce hogar".
Mis 2 centavos
fuente
AFIAK todos los idiomas con escritura dinámica son idiomas interpretados. Eso ya es muy ineficiente, agregar la ineficiencia del tipeo dinámico no será una gran pérdida de tiempo. Sin embargo, un lenguaje compilado no se referirá realmente a las cosas por su nombre cuando se esté ejecutando. (Salvo el uso ocasional de la reflexión .net o similar, características que son muy lentas en comparación con el lenguaje subyacente). La búsqueda de todos esos nombres será lenta, lenta, lenta.
fuente
Los lenguajes de tipo dinámico suelen promocionarse como "orientados a objetos". No son. Pueden estar orientados a la encapsulación, pero nunca a objetos. La orientación a objetos tiene que ver con los tipos.
"El niño monta la bicicleta de su hermano a la tienda de comestibles y compra una barra de pan de la tienda de comestibles". Usando la orientación a objetos, uno puede escribir inmediatamente un conjunto de clases (tipos) para describir este escenario del mundo real.
En un lenguaje de tipo dinámico, el escenario solo se puede representar de esta manera:
"El objeto monta el objeto de su objeto en el objeto y compra un objeto del objeto".
El poder de la orientación a objetos está en su capacidad de modelar el mundo en términos naturales, de modo que el desarrollador de software pueda usar ambos lados del cerebro para escribir software y resolver problemas más como un ser humano, menos como un programador de computadoras. Este poder está ausente en los idiomas de tipo dinámico.
La tipificación estática permite una mejor eficiencia de codificación, reutilización y mantenibilidad, porque los entornos de desarrollo integrados conocen los tipos de variables. Al conocer los tipos de variables, un IDE puede proporcionar la finalización automática para que el programador no tenga que volver a consultar la definición de clase para recordar si la propiedad del miembro se deletrea "backlightControl" o "backLightControl" o "bkLightCtrl".
La tipificación estática permite la refactorización automática, porque el IDE conoce cada lugar donde una variable contiene una instancia del objeto que se refactoriza.
La escritura estática permite una mayor reutilización y mantenibilidad. La escritura dinámica es mejor para el código desechable. Supongamos que un nuevo desarrollador entra en la calle y mira una pieza de código existente. Si el código se escribe estáticamente, el desarrollador puede, con dos clics del mouse, examinar la definición de clase de cada una de las variables involucradas, sabe para qué sirve la clase, sabe qué otros métodos y propiedades están disponibles. Si el código se escribe dinámicamente, el desarrollador debe usar la búsqueda global para descubrir qué está sucediendo.
fuente
Boy
clase, pero dudo que pueda hacer todo lo que hace un "niño" del mundo real. Sin embargo, en su ejemplo dinámico (El objeto se monta ...), sabemos lo único importante acerca de este objeto "niño": puede montarse . Esa es la filosofía básica de los lenguajes de tipo dinámico. Tiene + ve sy -ve s. Cuál te gusta es tu opinión.