回答:
C#の開発者自身から:
ポインターの使用がC#で必要になることはほとんどありませんが、ポインターを必要とする状況がいくつかあります。例として、安全でないコンテキストを使用してポインターを許可することは、次の場合に保証されます。
- ディスク上の既存の構造を扱う
- ポインターを含む構造を含む高度なCOMまたはプラットフォーム呼び出しシナリオ
- パフォーマンスが重要なコード
他の状況での安全でないコンテキストの使用は推奨されません。
具体的には、C#でCコードを記述しようとするために、安全でないコンテキストを使用しないでください。
注意: 「安全でないコンテキストを使用して記述されたコードは安全であると確認できないため、コードが完全に信頼されている場合にのみ実行されます。インターネットから直接コード。」
あなたはこれを参考にしてください
はい、パフォーマンスが重要で操作が低レベルの場合、実際の用途があります
たとえば、画像比較のためにC#で1回だけポインターを使用する必要がありました。1024x1024x32の画像のペアでGetPixelを使用すると、比較に2分かかりました(完全一致)。画像メモリを固定し、ポインタを使用するのに1秒もかかりませんでした(もちろん同じマシン上で)。
Microsoftのデザイナーは賢い人であり、C#に追加するものにはすべて少なくとも1つのユースケースがあることを覚えておく必要があります。FParsecプロジェクトは、 C#が可能であることが、パフォーマンスの最後の一滴を引き出すために、安全でないコードを使用しています。使用の通知を取るfixed
と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;
}
}
}
かつて、ヘッドセットへのインターフェイスとして機能するC#ベースのWindowsアプリケーションで(安全でないコンテキストで)ポインターを使用する必要がありました。このアプリケーションは、エージェント(コールセンター)がヘッドフォン設定を制御できるようにするユーザーインターフェイスです。このアプリケーションは、ヘッドセットメーカーが提供するコントロールパネルの代替として機能します。したがって、ヘッドセットを制御する機能は、利用可能なオプションと比較すると制限されていました。P / Invokeを使用してヘッドセットメーカーが提供するAPI(Visual C ++ dll)を使用する必要があるため、ポインターを使用する必要がありました。