มีการใช้พอยน์เตอร์ใน C # จริงหรือไม่ [ปิด]


19

สถานการณ์ในขณะที่เขียนโค้ดใน C # เมื่อใช้พอยน์เตอร์เป็นตัวเลือกที่ดีหรือจำเป็นคืออะไร ฉันกำลังพูดถึงพอยน์เตอร์ที่ไม่ปลอดภัย


8
คนอ่าฉันเห็นคำถามและมีความสุขเพราะฉันจะอธิบายว่าใน C # คุณใช้พอยน์เตอร์ตลอดเวลา แต่คุณต้องไปและทำลายโดยการพูดคำหลักที่ไม่ปลอดภัยอย่างชัดเจน Dang it! :)
Tony

คำตอบ:


25

จากนักพัฒนาของ C # ตัวเอง:

การใช้พอยน์เตอร์นั้นไม่ค่อยจำเป็นใน C # แต่มีบางสถานการณ์ที่ต้องใช้ ตัวอย่างเช่นการใช้บริบทที่ไม่ปลอดภัยเพื่ออนุญาตให้พอยน์เตอร์ได้รับการรับประกันในกรณีต่อไปนี้:

  • การจัดการกับโครงสร้างที่มีอยู่บนดิสก์
  • COM ขั้นสูงหรือแพลตฟอร์มเรียกใช้สถานการณ์สมมติที่เกี่ยวข้องกับโครงสร้างที่มีตัวชี้ในนั้น
  • รหัสประสิทธิภาพที่สำคัญ

การใช้บริบทที่ไม่ปลอดภัยในสถานการณ์อื่นนั้นไม่ได้รับการสนับสนุน

โดยเฉพาะอย่างยิ่งบริบทที่ไม่ปลอดภัยไม่ควรใช้เพื่อพยายามเขียนรหัส C ใน C #

ข้อควรระวัง: "รหัสที่เขียนโดยใช้บริบทที่ไม่ปลอดภัยไม่สามารถตรวจสอบได้ว่าปลอดภัยดังนั้นจะถูกดำเนินการเมื่อรหัสนั้นเชื่อถือได้อย่างสมบูรณ์เท่านั้นกล่าวอีกนัยหนึ่งรหัสที่ไม่ปลอดภัยจะไม่สามารถดำเนินการได้ในสภาพแวดล้อมที่ไม่น่าเชื่อถือตัวอย่างเช่น รหัสโดยตรงจากอินเทอร์เน็ต "

คุณสามารถทำสิ่งนี้เพื่อการอ้างอิง


"รหัสที่ไม่ปลอดภัยไม่สามารถดำเนินการในสภาพแวดล้อมที่ไม่น่าเชื่อถือ" คุณหมายถึง "เชื่อถือ" หรือไม่?
Don Larynx

18

ใช่มีการใช้งานจริงเมื่อประสิทธิภาพเป็นสิ่งสำคัญและการดำเนินการอยู่ในระดับต่ำ

เช่นฉันจำเป็นต้องใช้พอยน์เตอร์ใน C # เพียงครั้งเดียวเพื่อเปรียบเทียบภาพ การใช้ GetPixel ในรูปภาพขนาด 1024x1024x32 นั้นใช้เวลา 2 นาทีในการเปรียบเทียบ (จับคู่แบบตรงทั้งหมด) การจดจำหน่วยความจำภาพและการใช้ตัวชี้ใช้เวลาน้อยกว่า 1 วินาที (ในเครื่องเดียวกันแน่นอน)


2
ฉันมีคุณใช้ LockBits สำหรับที่ ... ( msdn.microsoft.com/en-us/library/ ...... )
กำหนดค่า

1
@ ผู้สร้าง: นี่คือ. net 2, LockBits ไม่มีอยู่จริง
Steven A. Lowe

2
แน่นอนว่ามันมีอยู่ตั้งแต่ 1.0 ...
กำหนดค่า

@ ผู้สร้าง: ข้อผิดพลาดของฉันฉันสับสนในการนำทางเอกสาร MSDN (เมื่อฉันเปลี่ยนเป็น. net 2 ใน droplist มันไปยังหน้าที่แตกต่างอย่างสิ้นเชิงที่ไม่ได้พูดถึง lockbits) ใช่นั่นคือวิธีที่คุณตรึงหน่วยความจำภาพ
Steven A. Lowe

6

คุณต้องจำไว้ว่านักออกแบบที่ Microsoft เป็นคนฉลาดและทุกอย่างที่พวกเขาเพิ่มใน C # มีกรณีการใช้งานอย่างน้อย 1 กรณี โครงการ FParsecใช้รหัสที่ไม่ปลอดภัยที่จะนำออกทุกหยดสุดท้ายของการแสดงที่ C # มีความสามารถใน จะแจ้งให้ทราบของการใช้งานของและfixedstackalloc

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;
        }
    }
}

1
ฉันจะบอกว่านักพัฒนา (ที่ Microsoft หรือ บริษัท อื่น ๆ ) จะเป็นคนงี่เง่าถ้าพวกเขามีคุณสมบัติบางอย่างเพราะมันมี 1 กรณีการใช้งาน คุณลักษณะควรมีมากกว่า 1 กรณีการใช้งานเท่านั้น มิฉะนั้นมันจะขยายตัว
Lie Ryan

4
เรย์มอนด์เฉินมักกล่าวว่าฟีเจอร์ที่ Microsoft เริ่มต้นที่ -100 "points" เพื่อให้สามารถใช้งานฟีเจอร์นี้ได้ "จะต้องมีผลบวกสุทธิอย่างมีนัยสำคัญต่อแพ็คเกจโดยรวมเพื่อให้สามารถใช้งานได้" ที่นี่โพสต์บล็อกของ ericgu เกี่ยวกับเรื่องนี้ c.2004: blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx
Jesse Buchanan

ฉันค่อนข้างมั่นใจว่าการใช้งาน String บางอย่างใช้รหัสที่ไม่ปลอดภัยภายใน ดังนั้น FParsec อาจไม่ได้รับความสำคัญ
Arturo Torres Sánchez

4

ฉันเคยต้องใช้พอยน์เตอร์ (ในบริบทที่ไม่ปลอดภัย) ในแอปพลิเคชัน windows ที่ใช้ C # ซึ่งจะทำหน้าที่เป็นส่วนต่อประสานกับชุดหูฟัง แอปพลิเคชั่นนี้เป็นอินเทอร์เฟซผู้ใช้ที่อนุญาตให้ตัวแทน (ที่ศูนย์บริการ) ควบคุมการตั้งค่าหูฟัง แอปพลิเคชั่นนี้ทำหน้าที่เป็นทางเลือกไปยังแผงควบคุมที่กำหนดโดยผู้ผลิตชุดหูฟัง ดังนั้นความสามารถในการควบคุมชุดหูฟังจึงมี จำกัด เมื่อเปรียบเทียบกับตัวเลือกที่มี ฉันต้องใช้พอยน์เตอร์เพราะฉันต้องใช้ API (DLL Visual C ++) ที่จัดทำโดยผู้ผลิตชุดหูฟังโดยใช้ P / Invoke

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.