2010-05-03 79 views
9

Đọc this question hôm nay về mã an toàn và không an toàn Tôi sau đó đọc về nó trong MSDN nhưng tôi vẫn không hiểu nó. Tại sao bạn muốn sử dụng con trỏ trong C#? Đây có phải là hoàn toàn cho tốc độ?Mã an toàn và không an toàn

+15

Nếu bạn là một người nhạy cảm thì bạn không bao giờ muốn * sử dụng con trỏ trong C#. Họ đang có cho những tình huống mà bạn * có * để sử dụng con trỏ trong C# cho dù bạn * muốn * đến hay không. :-) –

Trả lời

22

Có ba lý do để sử dụng mã không an toàn:

  • API (như ghi nhận của John)
  • Bắt địa chỉ thực tế bộ nhớ dữ liệu (ví dụ như bộ nhớ ánh xạ truy cập phần cứng)
  • cách hiệu quả nhất để truy cập và sửa đổi dữ liệu (các yêu cầu về hiệu suất thời gian quan trọng)
+6

Đối với ứng dụng thời gian quan trọng bằng cách sử dụng .net không phải là thông minh anyway. GC là không xác định và có thể đá trong mọi thời điểm. Mà về cơ bản vít lên bạn ứng dụng thời gian quan trọng. Các điểm khác tôi đồng ý btw! – Henri

+1

Một lý do khác mà tôi đã nghe nói về việc sử dụng C# không an toàn là đảm bảo rằng thông tin nhạy cảm về bảo mật, chẳng hạn như mật khẩu hoặc khóa mã hóa riêng, được xóa khỏi bộ nhớ tại một điểm xác định kịp thời. Nếu không, mật khẩu có thể treo trong bộ nhớ cho đến khi người khác muốn ghi vào cùng một vị trí. – harms

+1

Nó cũng đôi khi hữu ích trong các dự án đại học. –

5

Đôi khi bạn cần có con trỏ để giao diện C# của bạn với hệ điều hành cơ bản hoặc mã gốc khác. Bạn không được khuyến khích vì làm như vậy, vì nó là "không an toàn" (natch).

Sẽ có một số trường hợp rất hiếm khi hiệu suất của bạn bị ràng buộc CPU đến mức bạn cần thêm một chút hiệu suất. Khuyến nghị của tôi là viết những mẩu CPU-intesive trong một module riêng biệt trong assembly hoặc C/C++, export một API, và có mã .NET gọi API đó. Một lợi ích bổ sung có thể là bạn có thể đặt mã nền tảng cụ thể trong mô-đun không được quản lý và để nền tảng .NET bất khả tri.

+1

Tại sao bạn đề xuất chuyển đổi ngôn ngữ cho mã nhạy cảm với hiệu suất? Ưu điểm không rõ ràng. Tại sao không sử dụng đầy đủ các tính năng của ngôn ngữ C#? –

+0

Công cụ thích hợp cho đúng công việc? Nếu tôi định dùng con trỏ với các con trỏ và các công việc cấp thấp khác, tôi muốn làm điều đó với C/C++, nơi tôi có rất nhiều công cụ để xử lý. Những thứ hữu ích như lắp ráp nội tuyến, con trỏ dựa và các công cụ đẩy bit khác không được hỗ trợ trong C#. –

+0

Tôi đồng ý, khi viết bằng assembler hoặc C bạn cần phải quan tâm đến cách mã được biên dịch. – ChaosPandion

4

Tôi có xu hướng tránh nó, nhưng có một số khi nó rất hữu ích:

  • cho hiệu suất làm việc với bộ đệm thô (đồ họa, vv)
  • cần thiết đối với một số API không được quản lý (cũng khá hiếm hoi cho tôi)
  • cho gian lận với các dữ liệu

Ví dụ của cuối cùng, Tôi duy trì một số mã tuần tự hóa. Viết một float đến một dòng suối mà không cần phải sử dụng BitConverter.GetBytes (mà tạo ra một mảng mỗi lần) là đau đớn - nhưng tôi có thể lừa gạt:

float f = ...; 
int i = *(int*)&f; 

Bây giờ tôi có thể sử dụng thay đổi (>>) vv để viết i dễ dàng hơn nhiều so với viết f sẽ là (các byte sẽ giống hệt nếu tôi đã gọi là BitConverter.GetBytes, cộng với bây giờ tôi kiểm soát sự kết thúc bằng cách tôi chọn để sử dụng thay đổi).

+3

Tôi hiểu lý do tại sao bạn làm điều đó, nhưng mã đó trong C# chỉ khiến tôi rạn nứt. – Stephan

+0

Tôi chỉ phải cười khi thấy cái này: 'vì gian lận với dữ liệu'. Bạn làm tôi bực mình! Tôi không thể nói rằng tôi đã từng làm điều đó, nhưng ví dụ có ý nghĩa hoàn hảo! –

0

Có ít nhất một API .Net được quản lý thường sử dụng con trỏ không thể tránh khỏi. Xem SecureStringMarshal.SecureStringToGlobalAllocUnicode.

Các chỉ cách để có được những giá trị văn bản đơn giản của một SecureString là sử dụng một trong những phương pháp Marshal để sao chép nó vào bộ nhớ không được quản lý.