c# - son - punteros programacion
¿Deberías usar punteros(código inseguro) en C#? (11)
¿Deberías usar punteros en tu código C #? ¿Cuales son los beneficios? ¿Lo recomienda The Man (Microsoft)?
Debe usarlos si los necesita; mayormente esto será cuando trate con algunos escenarios complicados de interoperabilidad (por ejemplo, cuando escribí un contenedor administrado para DPAPI en .NET 1.0), pero muy ocasionalmente podría ser para mejorar el rendimiento (después del perfilado) mediante el uso de stackalloc
o similar.
Es recomendado por Microsoft en la medida en que son los diseñadores de C #, y tomaron la decisión de agregar la capacidad de escribir código unsafe
en él. Puede ver, a partir de la elección de la palabra clave y el requisito para delinear los métodos / clases en que la escribe con la palabra clave, que no está diseñada para ser la opción de implementación de facto.
Del propio "El Hombre":
El uso de punteros raramente se requiere en C #, pero hay algunas situaciones que lo requieren. Como ejemplos, el uso de un contexto inseguro para permitir punteros está garantizado por los siguientes casos:
- Tratando con las estructuras existentes en el disco
- Escenarios avanzados de invocación de plataforma o COM que implican estructuras con punteros en ellos
- Código de rendimiento crítico
El uso de contexto inseguro en otras situaciones no se recomienda.
Específicamente, un contexto inseguro no debe usarse para intentar escribir el código C en C #.
Precaución:
No se puede verificar que el código escrito usando un contexto inseguro sea seguro, por lo que se ejecutará solo cuando el código sea de plena confianza. En otras palabras, el código inseguro no se puede ejecutar en un entorno que no sea de confianza. Por ejemplo, no puede ejecutar código inseguro directamente desde Internet.
Hazlo si hace que tu código sea más corto y claro.
"Sigue tus inclinaciones con la debida atención al policía que está a la vuelta de la esquina". WSM
No recuerdo haber tenido que hacerlo, pero no hice mucha interoperabilidad. Esa es la aplicación más común, creo: llamando al código nativo. Hay algunas veces en que el uso de punteros te permite optimizar algunos códigos, pero es bastante raro en mi experiencia.
Si se trata de una guía, me considero bastante experimentado en C #, pero si tuviera que hacer algún código inseguro tendría que consultar las especificaciones / libros / MSDN para guiarme. Por supuesto, habrá muchas personas que estén contentas con el código inseguro pero menos familiarizadas con (por ejemplo) expresiones de consulta ...
Por supuesto, no es "recomendado", por eso está etiquetado como "inseguro". Pero no dejes que eso te asuste. Sin embargo, debería hacer que mires dos veces tu código. Tal vez hay una manera administrada de hacerlo?
Reinterpretivo como moldes no suministrados por BitConverter.
Convirtiendo específicamente un unint en un int para funciones hash donde todo lo que te importa son los bits.
Utilizando algunas funciones idiomáticas útiles, bien razonadas sobre c o C ++ en las estructuras donde necesita tratarlas como un byte * de una longitud bien conocida, de nuevo, más útil para el hash.
Una serialización binaria extremadamente rápida (muy específica) en las estructuras de memoria (haciéndolo en una matriz de ellas) aunque, para ser honesto, esto se hace mejor simplemente bajando a C ++ / CLI.
Debe decirse que, en muchos casos, la tarea que requiere punteros a menudo se puede resolver mejor haciéndolo en C ++ / CLI y luego importándolo en su proyecto c # como dll. No cambia si el código es "seguro" o no, pero hace que sea más accesible un conjunto de funciones útiles para operar en estructuras basadas en punteros. También le permite jugar con tipos genéricos o enumeraciones si realmente lo desea.
La probabilidad de que la mayoría de los desarrolladores necesiten hacer esto es realmente remota. Útil cuando lo necesitas, aunque ...
Si usted tiene que.
Supongamos que necesita aplicar falso color a una gran imagen en escala de grises, digamos 2000x2000 píxeles. Primero escriba la versión ''segura'' usando GetPixel()
y SetPixel()
. Si eso funciona, genial, sigue. si eso resulta ser demasiado lento, puede que necesite obtener los bits reales que componen la imagen (olvide las matrices de colores por el ejemplo). No hay nada "malo" en usar un código inseguro, pero agrega complejidad al proyecto y, por lo tanto, debe usarse solo cuando sea necesario.
Usar código inseguro es como olvidar los beneficios de .Net Framework, los utilicé una vez para crear estructuras anticuadas como pilas y cosas, pero eso fue solo para la escuela, hoy en día no he tenido la necesidad de usarlos.
Utilicé un código no seguro para usar la suplantación para permitir el acceso de los servicios a recursos compartidos de red. No es un problema si sabes lo que estás haciendo.
Yo diría que los principales problemas son:
- El código inseguro no es verificable. Esto significa que el código solo puede ejecutarlo un usuario desde un contexto completamente confiable, por lo tanto, si alguna vez necesita que un usuario ejecute el código desde cualquier lugar que no sea del todo confiable (por ejemplo, un recurso compartido de red no configurado para serlo), usted está atornillado.
- La falta de verificabilidad (no estoy seguro de si eso es realmente una palabra) también significa que podría perder memoria en su programa. Es posible que traigas clases enteras de errores a tu aplicación: desbordamientos de búfer, indicadores colgantes, yada yuck yuck. sin mencionar que potencialmente puede corromper las estructuras de datos en la memoria sin darse cuenta de cuándo el puntero se vuelve extraño.
- Si desea que su código no seguro acceda a los objetos administrados, debe ''fijarlos''. Esto significa que el GC no puede mover su objeto en la memoria y, por lo tanto, el montón administrado puede fragmentarse. Esto tiene implicaciones de rendimiento; por lo tanto, siempre es importante determinar si esta posible pérdida de rendimiento potencial no se ve superada.
- Su código se vuelve más difícil de entender para los programadores que no están acostumbrados al enfoque no administrado. Entonces pueden ser más propensos a dispararles con algo de la ''libertad'' que les da el código inseguro.
- Usted puede escribir código no seguro para tipos; esto realmente elimina bastante la ventaja de un buen lenguaje tibio administrado difuso. Ahora puede encontrar problemas de seguridad de tipo horrible. ¿Por qué dar ese paso atrás?
- Hace que tu código sea más feo .
Estoy seguro de que hay más que podrían agregarse a la lista; en general, como han dicho otros, evítelo, a menos que deba, por ejemplo, invocar un método no administrado a través de p / invoke, que requiera un puntero especial. Incluso entonces, el marshaller generalmente evitará la necesidad de eso, principalmente.
''El hombre'' también dice evitar a menos que sea necesario, básicamente.
Oh, buen artículo sobre fijar aquí en MSDN por cierto.
El código inseguro es una función totalmente compatible de .NET CLR. Los beneficios son el rendimiento y la compatibilidad con el código binario. El tiempo de ejecución es una caja de arena que evita que se bloquee y se queme, pero eso tiene un costo. En situaciones donde se realizan operaciones extremadamente intensas contra grandes blobs en la memoria, por ejemplo, manipulación de imágenes, es más rápido salirse de la seguridad normal que proporciona el tiempo de ejecución.
Habiendo dicho eso, creo que la mayoría de la gente diría "no lo hagas". La gran mayoría de los desarrolladores de .NET no se toparán con un caso en sus actividades normales que solo se puede resolver utilizando un código inseguro.