2010-08-08 48 views
14

C#: bạn có thể tạo nó để tham số phương thức truyền một đối tượng bằng tham chiếu nhưng chỉ đọc không?có thể tham số phương thức truyền đối tượng theo tham chiếu nhưng chỉ đọc không?

ví dụ:

void MyMethod(int x, int y, read-only MyObject obj) 

nơi obj là một tham chiếu đối tượng nhưng đối tượng này không thể được sửa đổi trong phương pháp này.

Điều này có thể đạt được trong C# không?

+0

bản sao có thể có của [Tại sao tham số const không được phép trong C#] (http: // stackoverflow.com/questions/3263001/why-const-parameters-are-not-allowed-in-c) – Incognito

+1

Câu hỏi đó hỏi tại sao tham số const không được phép. Câu hỏi của tôi hỏi liệu một tham số chỉ đọc có thể có trong C# hay không. Tôi không coi nó là một bản sao. – CJ7

Trả lời

15

No. C# không có tương tự trực tiếp với C++ const (const riêng của nó là một cái gì đó khác nhau). Một mẫu C# thông dụng cho điều này là truyền vào một giao diện, chẳng hạn như IEnumerable, không cho phép sửa đổi. Bạn cũng có thể tạo bản sao hoặc trình bao bọc bất biến.

+0

Bạn có thể xây dựng? Tôi có cần phải làm cho MyObject triển khai giao diện IEnumerable không? – CJ7

+1

'IEnumerable' là một ví dụ. Hãy nghĩ về sự khác biệt giữa 'IEnumerable' và' List'. Bạn có thể sửa đổi rõ ràng một 'List', nhưng nếu bạn sử dụng nó như là một' IEnumerable' (mà nó thực hiện), tất cả những gì bạn có thể làm là truy cập các phần tử theo thứ tự ('MoveNext' <->' Current'). Bạn có thể tạo giao diện của riêng mình với các thuộc tính chỉ đọc tương tự. –

+0

+1, điều này giống như câu trả lời của tôi, tôi không thấy nó. Nhưng tôi sẽ để tôi ở đó là "phiên bản dài". :) –

3

Điều này không thể thực hiện được trong C#.

Bạn có thể ngăn chặn điều này bằng cách truyền vào đối tượng không thay đổi.

+0

Làm thế nào bạn vượt qua nó là khác nhau từ bất biến, hai là hoàn toàn trực giao trong trường hợp của các đối tượng. –

+0

@Lasse - cảm ơn sự điều chỉnh. – Oded

0

Không có cơ chế nào thực hiện điều này cho bạn.

Hoặc là vượt qua một bản sao throwaway, hoặc xây dựng bất biến, ngay cả khi tạm thời, vào chính lớp đó.

+0

Bạn có nghĩa là giống như một bản sao của đối tượng gốc? – CJ7

+0

Vâng, chính xác, nếu điều đó là khả thi. Nếu bạn làm thế, thì những thay đổi không quan trọng. –

+0

Chi phí làm cho lớp học của bạn triển khai giao diện ICloneable là gì? – CJ7

0

tại sao bạn không tạo bản sao của đối tượng đó và làm bất cứ điều gì bạn muốn với bản sao đó trong khi obj của bạn vẫn không bị sửa đổi.

Xem ở đây làm thế nào để sao chép đối tượng của bạn: Deep cloning objects

+0

Một lý do tại sao bạn có thể không muốn tạo một bản sao là vì bạn lo lắng về chi phí hiệu suất của việc sao chép. –

+0

Tôi thích một giải pháp không làm tăng chi phí bộ nhớ. – CJ7

+0

Một vấn đề khác với gợi ý đó là người viết mã phương thức "nhận" có thể giả định rằng những thay đổi trạng thái mà chúng gây ra trên đối tượng sẽ là vĩnh viễn, khi thực tế chúng sẽ bị vứt bỏ. –

4

Nếu lớp của đối tượng bạn đang đi qua đã được viết bởi bạn, sau đó bạn đang ở may mắn.

Hãy tự hỏi: nếu C# có tính năng const, hoạt động nào trên đối tượng tôi sẽ bị cấm thông qua tham chiếu const đối với lớp học của tôi?

Sau đó, xác định interface để loại bỏ các hoạt động bị cấm.

Ví dụ:

class MyClass 
{ 
    public string GetSomething() { ... } 

    public void Clobber() { ... } 

    public int Thing { get { ... } set { ... } } 
} 

Các tương ứng "const" giao diện có thể là:

interface IConstMyClass 
{ 
    public string GetSomething() { ... } 

    public int Thing { get { ... } } 
} 

Bây giờ sửa đổi các lớp:

class MyClass : IConstMyClass 
{ 

Bây giờ bạn có thể sử dụng IConstMyClass nghĩa const MyClass .

void MyMethod(int x, int y, IConstMyClass obj) 

Lưu ý: sẽ có những người sẽ cho bạn biết rằng điều này là không đủ. Nếu MyMethod quay lại MyClass thì sao? Nhưng bỏ qua chúng. Cuối cùng người triển khai có thể sử dụng sự phản chiếu để có được xung quanh bất kỳ khía cạnh nào của hệ thống kiểu - see this amusing example.

Tùy chọn duy nhất để ngừng các cuộc tấn công phản chiếu là cách tiếp cận tầm thường: tạo một bản sao hoàn toàn bị ngắt kết nối.

+0

Mặc dù một câu trả lời khác về cơ bản là giống nhau, tôi thực sự đánh giá cao nỗ lực bổ sung để giải thích nó rất tốt theo cách mà một lập trình viên CPP sẽ hiểu. Câu trả lời này là một nỗ lực nổi bật rất hữu ích. – shawn1874

+0

@ shawn1874 - cảm ơn, những phản hồi tuyệt vời! :) –

Các vấn đề liên quan