İşaretçileri kullanmanın iyi veya gerekli bir seçenek olduğu C # 'da kodlarken durum nedir? Güvensiz işaretçilerden bahsediyorum .
İşaretçileri kullanmanın iyi veya gerekli bir seçenek olduğu C # 'da kodlarken durum nedir? Güvensiz işaretçilerden bahsediyorum .
Yanıtlar:
C # geliştiricisinin kendisinden:
C # 'da işaretçilerin kullanımı nadiren gereklidir, ancak bunları gerektiren bazı durumlar vardır. Örnek olarak, işaretleyicilere izin vermek için güvenli olmayan bir bağlam kullanmak aşağıdaki durumlarda garanti edilir:
- Diskteki mevcut yapılarla başa çıkmak
- Gelişmiş COM veya Platform İşaretçileri olan yapıları içeren senaryoları çağırın
- Performans açısından kritik kod
Güvenli olmayan bağlamın başka durumlarda kullanılması önerilmez.
Özellikle, C # 'da C kodu yazmaya çalışmak için güvenli olmayan bir bağlam kullanılmamalıdır.
Dikkat: "Güvenli olmayan bir bağlam kullanılarak yazılan kodun güvenli olduğu doğrulanamaz, bu nedenle yalnızca kod tam olarak güvenilir olduğunda çalıştırılır. Başka bir deyişle, güvenli olmayan kod güvenilir olmayan bir ortamda yürütülemez. Örneğin kodunu doğrudan İnternet'ten girin. "
Sen geçebilir bu başvuru için
evet, performans kritik olduğunda ve işlemler düşük seviyedeyse gerçek kullanımlar vardır
Örneğin, görüntü karşılaştırma için yalnızca bir kez C # işaretçileri kullanmak gerekiyor. Bir çift 1024x1024x32 görüntü üzerinde GetPixel kullanmak karşılaştırmayı yapmak için 2 dakika sürdü (Tam eşleme). Görüntü belleğinin sabitlenmesi ve işaretçilerin kullanılması 1 saniyeden daha az sürdü (elbette aynı makinede).
Microsoft tasarımcılarının akıllı insanlar olduğunu ve C # 'a ekledikleri her şeyin en az 1 kullanım durumu olduğunu hatırlamanız gerekir. FParsec projesi C # yeteneğine sahip olduğunu performansın son damlasına ortaya çıkarmak için güvensiz kod kullanır. Kullanımının Duyurulur fixed
ve 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;
}
}
}
Bir kez bir kulaklık arabirimi olarak hareket C # tabanlı bir windows uygulamasında işaretçiler (güvenli olmayan bağlamda) kullanmak zorunda kaldı. Bu uygulama, ajanların (çağrı merkezinde) kulaklık ayarlarını kontrol etmesine izin veren bir kullanıcı arayüzüdür. Bu uygulama, kulaklık üreticisi tarafından verilen kontrol paneline alternatif olarak işlev görür. Böylece, kulaklıkları kontrol etme yetenekleri mevcut seçeneklerle karşılaştırıldığında sınırlıydı. P / Invoke kullanarak kulaklık üreticisi tarafından sağlanan API (bir Visual C ++ dll) kullanmak zorunda çünkü işaretçiler kullanmak zorunda kaldı.