Bất kỳ việc sử dụng con trỏ thực sự trong C #? [đóng cửa]


19

Tình huống trong khi mã hóa trong C # trong đó sử dụng con trỏ là một lựa chọn tốt hoặc cần thiết? Tôi đang nói về con trỏ không an toàn .


8
Ahhh, tôi đã thấy câu hỏi và rất vui vì tôi sẽ giải thích rằng trong C # bạn sử dụng con trỏ mọi lúc nhưng bạn phải đi và làm hỏng nó bằng cách nói rõ ràng từ khóa không an toàn. Đằng đó! :)
Tony

Câu trả lời:


25

Từ chính nhà phát triển C #:

Việc sử dụng con trỏ hiếm khi được yêu cầu trong C #, nhưng có một số tình huống yêu cầu chúng. Ví dụ, sử dụng bối cảnh không an toàn để cho phép con trỏ được bảo đảm bởi các trường hợp sau:

  • Xử lý các cấu trúc hiện có trên đĩa
  • COM hoặc Nền tảng nâng cao Gọi các kịch bản liên quan đến các cấu trúc có con trỏ trong đó
  • Mã hiệu suất quan trọng

Việc sử dụng bối cảnh không an toàn trong các tình huống khác là không được khuyến khích.

Cụ thể, không nên sử dụng bối cảnh không an toàn để cố gắng viết mã C trong C #.

Thận trọng: "Mã được viết bằng bối cảnh không an toàn không thể được xác minh là an toàn, do đó, mã sẽ chỉ được thực thi khi mã được tin cậy hoàn toàn. Nói cách khác, mã không an toàn không thể được thực thi trong môi trường không tin cậy. Ví dụ: bạn không thể chạy không an toàn. mã trực tiếp từ Internet. "

Bạn có thể đi qua đây để tham khảo


"mã không an toàn không thể được thực thi trong một môi trường không tin cậy." Ý bạn là "đáng tin cậy"?
Don Larynx

18

có, có những ứng dụng thực sự, khi hiệu suất là quan trọng và các hoạt động ở mức độ thấp

ví dụ: tôi chỉ cần sử dụng con trỏ trong C # một lần, để so sánh hình ảnh. Sử dụng GetPixel trên một cặp hình ảnh 1024x1024x32 mất 2 phút để thực hiện so sánh (Kết hợp chính xác). Việc ghim bộ nhớ hình ảnh và sử dụng các con trỏ chỉ mất chưa đến 1 giây (tất nhiên trên cùng một máy).


2
Tôi có bạn đã sử dụng LockBits cho điều đó ... ( msdn.microsoft.com/en-us/l Library / Bt )
cấu hình

1
@configurator: đây là .net 2, LockBits không tồn tại
Steven A. Lowe

2
Chắc chắn là có, nó tồn tại từ 1.0 ...
cấu hình

@configurator: lỗi của tôi, tôi đã nhầm lẫn khi điều hướng tài liệu MSDN (khi tôi đổi thành .net 2 trong trình duyệt, nó đã chuyển đến một trang hoàn toàn khác không đề cập đến khóa). Vâng, đó là cách bạn ghim bộ nhớ hình ảnh.
Steven A. Lowe

6

Bạn phải nhớ rằng các nhà thiết kế tại Microsoft là những người thông minh và mọi thứ họ thêm vào C # đều có ít nhất 1 trường hợp sử dụng. Các dự án FParsec sử dụng mã không an toàn để đưa ra từng giọt cuối cùng của hiệu suất mà C # là có khả năng. Hãy chú ý đến việc sử dụng 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
Tôi muốn nói rằng các nhà phát triển (tại Microsoft hoặc bất kỳ công ty nào khác) sẽ là một thằng ngốc nếu họ bao gồm một số tính năng vì nó có 1 trường hợp sử dụng. Một tính năng nên có nhiều hơn chỉ 1 trường hợp sử dụng; nếu không thì nó là một sự phình to
Lie Ryan

4
Raymond Chen thường nói rằng các tính năng tại Microsoft bắt đầu ở mức -100 "điểm". Để một tính năng được triển khai, nó "phải có tác động tích cực đáng kể đến gói tổng thể để nó được đưa vào". Dưới đây là bài viết trên blog ericgu về c.2004 này: blogs.msdn.com/b/ericgu/archive/2004/01/12/57985.aspx
Jesse Buchanan

Tôi khá chắc chắn rằng một số hoạt động Chuỗi bên trong sử dụng mã không an toàn. Vì vậy, FParsec có thể không được ưu tiên.
Arturo Torres Sánchez

4

Tôi đã từng phải sử dụng các con trỏ (trong ngữ cảnh không an toàn) trong ứng dụng windows dựa trên C # sẽ hoạt động như một giao diện cho tai nghe. Ứng dụng này là giao diện người dùng cho phép các đại lý (tại trung tâm cuộc gọi) kiểm soát cài đặt tai nghe của họ. Ứng dụng này hoạt động như một sự thay thế cho bảng điều khiển được cung cấp bởi nhà sản xuất tai nghe. Do đó, khả năng kiểm soát tai nghe của họ bị hạn chế khi so sánh với các tùy chọn có sẵn. Tôi đã phải sử dụng con trỏ vì tôi phải sử dụng API (một dll Visual C ++) được cung cấp bởi nhà sản xuất tai nghe bằng P / Invoke.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.