C #: beneficio de la declaración explícita & # 8220; unsafe & # 8221; / opción del compilador

StackOverflow https://stackoverflow.com/questions/607159

Pregunta

Entiendo los punteros y la rara necesidad de usarlos en el código C #. Mi pregunta es: ¿cuál es el razonamiento detrás de tener que declarar explícitamente " inseguro " en un bloque de código Además, ¿por qué se debe cambiar una opción del compilador para permitir " insegura " código?

Conclusión: Lo que en CLR (o especificaciones de idioma) hace que no podamos usar punteros cuando lo deseemos (como C y C ++) sin tener que escribir " inseguro " y cambiar la opción del compilador?

Para aclarar: sé lo que " inseguro " y " seguro " el código es. Es solo una cuestión de por qué debemos hacer todo el trabajo adicional (bueno, no ES TANTO extra) solo para poder usar estas funciones.

¿Fue útil?

Solución

Hay una entrevista con el creador de C # Anders Hejlsberg que aborda el tema aquí . Básicamente, exactamente lo que dijo @Marc Gravell: tipos de seguridad primero, inseguridad por declaración explícita.

Entonces, para responder a tu pregunta: nada en el CLR lo impide; es un lenguaje de lenguaje diseñado para permitirle trabajar con guantes de seguridad cuando se trata de tipos. Si desea quitarse los guantes, es su elección, pero tiene que tomar la decisión activa de quitarse los guantes.

Editar:

  

Para aclarar: sé qué   " inseguro " y " seguro " el código es. Es solo   Una pregunta de por qué debemos hacer todo el   trabajo extra (ok, no que mucho extra)   solo para poder utilizar estas funciones.

Como mencioné en la entrevista que vinculé, fue una decisión de diseño explícita. C # es esencialmente una evolución de Java y en Java, no tiene ningún tipo de punteros. Pero los diseñadores querían permitir punteros; sin embargo, debido a que C # normalmente traería desarrolladores de Java, sintieron que sería mejor si el comportamiento predeterminado fuera similar a Java, es decir, sin punteros, mientras que aún permite el uso de punteros por declaración explícita.

Así que el " trabajo extra " es deliberado para obligarlo a pensar en lo que está haciendo antes de hacerlo. Al ser explícito, te obliga a al menos considerar: " ¿Por qué estoy haciendo esto? ¿Necesito realmente un puntero cuando un tipo de referencia será suficiente? & Quot;

Otros consejos

En gran parte se trata de ser verificable. Al indicar no seguro , los guantes están apagados: el sistema ya no puede garantizar que su código no se cometerá un error. En la mayoría de los casos, es muy conveniente permanecer en la zona segura.

Esto se hace más evidente con la confianza parcial (complementos, etc.), pero aún es valioso en el código regular.

En realidad, el CLR no establece ningún requisito sobre un conmutador / inseguro o palabra clave. De hecho, C ++ / CLI (el lenguaje C ++ que se ejecuta bajo el CLR) no tiene tal interruptor / inseguro, y los punteros se pueden usar libremente en el CLR.

Entonces, reformularía su pregunta como " ¿Por qué C # requiere el uso de / unsafe antes de que se puedan usar los punteros? " Y la respuesta a esa pregunta es la que se indica en otras respuestas proporcionadas aquí: para ayudar al usuario a tomar una decisión consciente de perder la capacidad de ejecutar en cualquier modo que no sea el modo de plena confianza en el CLR. C ++ prácticamente siempre requiere Full Trust en el CLR, y C # puede siempre que llame al código que requiere Full Trust, o siempre que use punteros.

Cuando usa un bloque inseguro, tiene el efecto de hacer que el código no sea verificable. Esto requiere ciertos permisos para ejecutarse y es posible que no desee permitirlo en su salida (especialmente si se encuentra en un entorno de origen compartido), por lo que hay un interruptor en el compilador para no permitirlo.

Piénselo desde el punto de vista opuesto: como no está marcado como no seguro, puede inferir que la mayoría del código es " seguro " por defecto. Entonces, ¿qué significa ser " seguro " ;? Para el código .Net, esto incluye (pero no se limita a):

  • El recolector de basura puede hacer negocios como de costumbre.
  • Las referencias a un tipo específico se se referirán a objetos de ese tipo (o nulo).
  • Se garantiza que el código cumple con los requisitos de confianza / seguridad de .Net.
  • Se ha demostrado matemáticamente que el código no toca directamente la memoria fuera de su propio dominio de aplicación. Puede parecer trivial, pero imagine que tiene varios AppDomains en la misma aplicación. El programador puede tratarlos con confianza como lógicamente separados.

Cada vez que uses punteros, tienes la oportunidad de romper cualquiera de esas garantías. Por lo tanto, marcar el código como inseguro renuncia a esas protecciones.

En resumen, .NET quiere que declares tu intención.

Claro, el compilador podría inferir la necesidad de " unsafe " bandera. Pero los diseñadores quieren que sea una decisión deliberada.

Para mí, es similar a una serie de requisitos sintácticos en C #:

  • no hay caja de interruptores sin interrupción
  • no hay secciones de nivel de acceso " " (como el " público: " marcador en C ++)
  • no hay campos de clase usando " var "

El patrón es que no debes mover o cambiar una cosa y afectar inadvertidamente a otra. Dentro de lo razonable, quieren evitar que " se dispare en el pie. & Quot;

Muchas respuestas geniales e informativas aquí, tal vez esto vaya más a tu pregunta.

Por lo que es inmediatamente obvio qué código no se ejecutará en servicios web sin permisos elevados, etc.

Cultivando buenos hábitos y amp; seguridad. Siempre que use un bloque inseguro en un ensamblaje, se solicitará un permiso de NativeCode de la pila. Por supuesto, esto podría hacerse de manera implícita, pero ¿no podríamos eliminar la palabra clave privada por completo? Creo que es bueno obligar a los desarrolladores a exigir específicamente un código no seguro antes de que puedan usarlo.

La diferencia más significativa entre el código seguro y el inseguro es que el recolector de basura de .net no puede acceder al código inseguro. El GC automático es una gran parte de la lengua vernácula de .net y, cuando va más allá de sus límites, cambia mucho de lo que se puede suponer sobre su código.

Los punteros en particular permiten la creación de objetos en el montón sin referencias de GC. Esto lleva a otra excelente razón para exigir que el código se marque como "inseguro". Hace que sea más fácil determinar de dónde proviene una pérdida de memoria cuando te das cuenta de que tienes una.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top