¿Cuál es una situación mientras se codifica en C # donde el uso de punteros es una buena o necesaria opción? Estoy hablando de punteros inseguros .
¿Cuál es una situación mientras se codifica en C # donde el uso de punteros es una buena o necesaria opción? Estoy hablando de punteros inseguros .
Respuestas:
Del desarrollador del propio C #:
El uso de punteros rara vez se requiere en C #, pero hay algunas situaciones que los requieren. Como ejemplos, el uso de un contexto inseguro para permitir punteros está garantizado por los siguientes casos:
- Manejo de estructuras existentes en disco
- Escenarios de COM avanzado o invocación de plataforma que involucran estructuras con punteros en ellos
- Código de rendimiento crítico
Se desaconseja el uso de contextos inseguros en otras situaciones.
Específicamente, un contexto inseguro no debe usarse para intentar escribir código C en C #.
Precaución: "El código escrito utilizando un contexto inseguro no puede verificarse como seguro, por lo que se ejecutará solo cuando el código sea totalmente confiable. En otras palabras, el código inseguro no se puede ejecutar en un entorno no confiable. Por ejemplo, no puede ejecutar inseguro código directamente desde Internet ".
Puedes pasar por esto como referencia
Sí, hay usos reales, cuando el rendimiento es crítico y las operaciones son de bajo nivel.
por ejemplo, solo necesito usar punteros en C # una vez, para comparar imágenes. El uso de GetPixel en un par de imágenes de 1024x1024x32 tomó 2 minutos para hacer la comparación (coincidencia exacta). Fijar la memoria de imagen y usar punteros tomó menos de 1 segundo (en la misma máquina, por supuesto).
Debe recordar que los diseñadores de Microsoft son personas inteligentes y todo lo que agregan a C # tiene al menos 1 caso de uso. El proyecto FParsec utiliza código inseguro para mostrar hasta la última caída de rendimiento que C # es capaz de hacer. Tome nota del uso de fixed
y stackalloc
.
private char* ReadCharsFromStream(char* buffer, int maxCount, out string overhangChars) {
Debug.Assert(maxCount >= 0);
fixed (byte* byteBuffer = ByteBuffer) {
overhangChars = null;
try {
while (maxCount >= MaxCharCountForOneByte) {// if maxCount < MaxCharCountForOneByte, Convert could throw
int nBytesInByteBuffer = FillByteBuffer();
bool flush = nBytesInByteBuffer == 0;
int bytesUsed, charsUsed; bool completed = false;
Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
buffer, maxCount, flush,
out bytesUsed, out charsUsed, out completed);
ByteBufferIndex += bytesUsed; // GetChars consumed bytesUsed bytes from the byte buffer
buffer += charsUsed;
maxCount -= charsUsed;
if (flush && completed) return buffer;
}
if (maxCount == 0) return buffer;
char* cs = stackalloc char[MaxCharCountForOneByte];
for (;;) {
int nBytesInByteBuffer = FillByteBuffer();
bool flush = nBytesInByteBuffer == 0;
int bytesUsed, charsUsed; bool completed;
Decoder.Convert(byteBuffer + ByteBufferIndex, nBytesInByteBuffer,
cs, MaxCharCountForOneByte, flush,
out bytesUsed, out charsUsed, out completed);
ByteBufferIndex += bytesUsed;
if (charsUsed > 0) {
int i = 0;
do {
*(buffer++) = cs[i++];
if (--maxCount == 0) {
if (i < charsUsed) overhangChars = new string(cs, i, charsUsed - i);
return buffer;
}
} while (i < charsUsed);
}
if (flush && completed) return buffer;
}
} catch (DecoderFallbackException e) {
e.Data.Add("Stream.Position", ByteIndex + e.Index);
throw;
}
}
}
Una vez tuve que usar punteros (en el contexto inseguro) en una aplicación de Windows basada en C # que actuaría como una interfaz para un auricular. Esta aplicación es una interfaz de usuario que permitiría a los agentes (en un centro de llamadas) controlar la configuración de sus auriculares. Esta aplicación actúa como una alternativa al panel de control proporcionado por el fabricante del auricular. Por lo tanto, su capacidad para controlar los auriculares era limitada en comparación con las opciones disponibles. Tuve que usar punteros porque tuve que usar la API (un dll de Visual C ++) proporcionada por el fabricante de auriculares usando P / Invoke.