2011-08-23 39 views
7

Tôi hiểu rằng phương pháp mở rộng C# phải tĩnh. Những gì tôi không hiểu là lý do tại sao các phần mở rộng không thể được định nghĩa trong các lớp không tĩnh hoặc chung?Tại sao các phương thức mở rộng C# phải được định nghĩa trong các lớp tĩnh?

Cập nhật: Tôi quan tâm đến lý do đằng sau quyết định thiết kế này.

+0

Tôi tìm kiếm thông qua cho trường hợp lớp tĩnh trước khi đặt câu hỏi này và tôi không tìm thấy câu trả lời bạn đã đề cập đến. Bằng cách này nó không chính xác cùng một câu hỏi và câu trả lời của tôi không được tìm thấy trong bài viết đó. – Mehran

+0

Làm thế nào là một * chính xác * trùng lặp của "Tại sao nó không thể khai báo các phương pháp mở rộng trong một lớp tĩnh chung?". –

+0

Đây không phải là bản sao. Thay vào đó là một câu hỏi cụ thể hơn từ cái gọi là gấp đôi. –

Trả lời

5

Đây là chi tiết của một quan sát hơn một câu trả lời, nhưng ...

Khi bạn gọi một phương pháp dụ, một tham chiếu đến đối tượng bạn đang gọi được đẩy vào stack như là đối số đầu tiên trong bạn gọi phương thức. Lập luận đầu tiên là "này" và được thực hiện hoàn toàn.

Khi bạn xác định một phương pháp mở rộng, bạn xác định rõ ràng một "this" làm đối số đầu tiên.

Có thể độ phân giải của phương pháp sẽ gây nhầm lẫn nếu bạn có thể xác định phương pháp mở rộng phương pháp thể hiện trong cùng một phương thức xác định với cùng tên và, có hiệu lực, cùng thông số khi tham số "this" bao gồm.

+0

Đó là một quan sát tuyệt vời và cũng là một điều đáng tin cậy. Cảm ơn bạn đã chia sẻ nó. – Mehran

+0

Có lẽ, ngoại trừ IMHO có thực sự phải là một ngoại lệ lớn đối với quy tắc: một lớp hoặc cấu trúc nên được phép định nghĩa các thành viên mở rộng hoạt động trên các thành viên thuộc loại riêng của nó, và trong trường hợp của cấu trúc, nó sẽ có thể cho thông số "này" phải theo giá trị hoặc tham chiếu. Các phương thức mở rộng như vậy sẽ cho phép các kiểu lớp bất biến hoạt động giống như các kiểu giá trị liên quan đến khởi tạo và cho phép cú pháp 'phương thức' bình thường được sử dụng trên các trình biến đổi cấu trúc mà không có nguy cơ chúng được áp dụng trong các ngữ cảnh chỉ đọc. – supercat

+0

@supercat Nếu bạn có thể định nghĩa một phương thức mở rộng trong một lớp để tự hành động, nó sẽ không phải là một phương thức mở rộng? –

1

Vì thông số kỹ thuật nói như vậy ... Bây giờ có thể có lý do chính đáng tại sao họ đã viết thông số theo cách này.

Lý do tại sao chúng không thể được khai báo trong các lớp chung là khá rõ ràng: với cách thức các phương thức mở rộng được gọi, bạn sẽ chỉ định đối số kiểu cho lớp ở đâu?

Lý do tại sao nó phải là một lớp tĩnh ít rõ ràng hơn, nhưng tôi nghĩ nó có ý nghĩa. Trường hợp sử dụng chính cho các lớp tĩnh là nhóm các phương thức trợ giúp nhóm lại với nhau (ví dụ: Path, Directory, ProtectedData ...) và các phương thức mở rộng là các phương thức trợ giúp cơ bản. Chẳng có ý nghĩa gì nếu có thể tạo ra một ví dụ của Enumerable hoặc Queryable.

+0

Tôi hiểu những gì spec nói. Tôi quan tâm để biết lý do tại sao quyết định thiết kế này được thực hiện. – Mehran

+0

@Mehran, đó là chính xác những gì tôi đã cố gắng để giải thích trong câu trả lời của tôi ... Tôi đã không lặp lại những gì spec nói. –

+1

Các phương thức mở rộng công cộng chỉ có ý nghĩa ở một lớp tĩnh cấp cao, nhưng các quy tắc có thể cho phép các phương thức mở rộng được khai báo trong các lớp riêng tư hoặc được bảo vệ lồng nhau, với điều kiện là các phương thức đó sẽ chỉ có thể sử dụng được. Ví dụ, mã cho lớp 'Foo ' có thể hưởng lợi từ việc có thể định nghĩa một phương thức mở rộng sử dụng một kiểu riêng tư cho 'Foo '. Một phương thức mở rộng như vậy sẽ không có vấn đề gì khi biết 'T' nào sử dụng, vì mã duy nhất có thể thấy nó sẽ có kiểu đó. – supercat

3

Hãy xem để mảnh này của .NET C# đặc điểm kỹ thuật:

Khi tham số đầu tiên của một phương pháp bao gồm việc sửa đổi lần này, đó là phương pháp được cho là một phương pháp mở rộng. Các phương thức mở rộng chỉ có thể được khai báo trong các lớp tĩnh không chung, không lồng nhau. Tham số đầu tiên của một phương pháp mở rộng có thể không có biến tố nào khác ngoài điều này và loại thông số không thể là loại con trỏ.

Và đoạn này từ Jon Skeet's answer:

Nó không rõ ràng với tôi lý do tại sao tất cả những hạn chế này là cần thiết - khác hơn là khả năng cho trình biên dịch (và ngôn ngữ spec) đơn giản. Tôi có thể thấy lý do tại sao nó có ý nghĩa để hạn chế nó để loại không chung chung, nhưng tôi không thể ngay lập tức thấy lý do tại sao họ phải được không lồng nhau và tĩnh. Tôi nghi ngờ nó làm cho các quy tắc tìm kiếm đơn giản hơn đáng kể nếu bạn không phải lo lắng về các loại có trong loại hiện tại v.v., nhưng tôi dám nói rằng điều đó là có thể.

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