Was ist eine Situation beim Codieren in C #, in der die Verwendung von Zeigern eine gute oder notwendige Option ist? Ich spreche von unsicheren Zeigern.
Was ist eine Situation beim Codieren in C #, in der die Verwendung von Zeigern eine gute oder notwendige Option ist? Ich spreche von unsicheren Zeigern.
Antworten:
Vom Entwickler von C # selbst:
Die Verwendung von Zeigern ist in C # selten erforderlich, es gibt jedoch Situationen, in denen dies erforderlich ist. Die Verwendung eines unsicheren Kontexts zum Zulassen von Zeigern ist beispielsweise in den folgenden Fällen gerechtfertigt:
- Umgang mit vorhandenen Strukturen auf der Festplatte
- Erweiterte COM- oder Platform-Invoke-Szenarien, in denen Strukturen mit Zeigern enthalten sind
- Leistungskritischer Code
Von der Verwendung von unsicherem Kontext in anderen Situationen wird abgeraten.
Insbesondere sollte kein unsicherer Kontext verwendet werden, um zu versuchen, C-Code in C # zu schreiben.
Achtung: "Code, der mit einem unsicheren Kontext geschrieben wurde, kann nicht als sicher überprüft werden. Daher wird er nur ausgeführt, wenn der Code vollständig vertrauenswürdig ist. Mit anderen Worten, unsicherer Code kann in einer nicht vertrauenswürdigen Umgebung nicht ausgeführt werden. Beispielsweise können Sie unsicher nicht ausführen Code direkt aus dem Internet. "
Sie können dies als Referenz durchgehen
Ja, es gibt echte Anwendungen, wenn die Leistung kritisch ist und die Vorgänge auf niedrigem Niveau sind
Zum Beispiel musste ich Zeiger in C # nur einmal für den Bildvergleich verwenden. Die Verwendung von GetPixel für ein Paar von 1024 x 1024 x 32-Bildern dauerte 2 Minuten, um den Vergleich durchzuführen (genaue Übereinstimmung). Das Fixieren des Bildspeichers und das Verwenden von Zeigern dauerte weniger als 1 Sekunde (auf demselben Computer natürlich).
Sie müssen sich daran erinnern, dass die Designer bei Microsoft clevere Leute sind und alles, was sie zu C # hinzufügen, mindestens einen Anwendungsfall hat. Das FParsec-Projekt verwendet unsicheren Code, um den letzten Leistungsabfall zu erzielen, zu dem C # in der Lage ist. Beachten Sie die Verwendung von fixed
und 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;
}
}
}
Ich musste einmal Zeiger (im unsicheren Kontext) in einer C # -basierten Windows-Anwendung verwenden, die als Schnittstelle zu einem Headset fungieren würde. Diese Anwendung ist eine Benutzeroberfläche, über die Agenten (in einem Callcenter) ihre Kopfhörereinstellungen steuern können. Diese Anwendung fungiert als Alternative zum Bedienfeld des Headset-Herstellers. Daher war ihre Fähigkeit zur Steuerung der Headsets im Vergleich zu den verfügbaren Optionen eingeschränkt. Ich musste Zeiger verwenden, da ich die API (eine Visual C ++ - DLL) verwenden musste, die vom Hersteller des Headsets mithilfe von P / Invoke bereitgestellt wurde.