O que é uma situação ao codificar em C # em que o uso de ponteiros é uma opção boa ou necessária? Estou falando de indicadores inseguros .
O que é uma situação ao codificar em C # em que o uso de ponteiros é uma opção boa ou necessária? Estou falando de indicadores inseguros .
Respostas:
Do desenvolvedor do próprio C #:
O uso de ponteiros raramente é necessário em C #, mas há algumas situações que os exigem. Como exemplos, o uso de um contexto não seguro para permitir ponteiros é garantido pelos seguintes casos:
- Lidando com estruturas existentes no disco
- Cenários avançados de COM ou Platform Invoke que envolvem estruturas com ponteiros neles
- Código crítico de desempenho
O uso de contexto inseguro em outras situações é desencorajado.
Especificamente, um contexto não seguro não deve ser usado para tentar escrever código C em C #.
Cuidado: "O código gravado usando um contexto não seguro não pode ser verificado como seguro; portanto, ele será executado apenas quando o código for totalmente confiável. Em outras palavras, o código não seguro não poderá ser executado em um ambiente não confiável. Por exemplo, você não pode executar não seguro. código diretamente da Internet ".
Você pode passar por isso para referência
sim, existem usos reais, quando o desempenho é crítico e as operações são de baixo nível
por exemplo, eu só precisei usar ponteiros em c # uma vez, para comparação de imagens. O uso do GetPixel em um par de imagens de 1024x1024x32 levou 2 minutos para fazer a comparação (correspondência exata). Fixar a memória da imagem e usar ponteiros levou menos de 1 segundo (na mesma máquina, é claro).
Você deve se lembrar que os designers da Microsoft são pessoas inteligentes e tudo o que adicionam ao C # tem pelo menos 1 caso de uso. O projeto FParsec usa código não seguro para trazer toda a última gota de desempenho que o C # é capaz. Observe o uso de fixed
e 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;
}
}
}
Uma vez eu tive que usar ponteiros (no contexto inseguro) em um aplicativo Windows baseado em C # que atuaria como uma interface para um fone de ouvido. Esse aplicativo é uma interface do usuário que permitiria aos agentes (em um call center) controlar suas configurações de fone de ouvido. Este aplicativo funciona como uma alternativa ao painel de controle fornecido pelo fabricante do fone de ouvido. Assim, sua capacidade de controlar os fones de ouvido era limitada quando comparada às opções disponíveis. Eu tive que usar ponteiros porque tive que usar a API (uma DLL do Visual C ++) fornecida pelo fabricante do fone de ouvido usando P / Invoke.