2009-05-22 69 views
88

Đã có những trường hợp tôi muốn ghi đè phương thức trong một lớp học bằng một phương thức mở rộng. Có cách nào để làm điều đó trong C#?Có cách nào trong C# để ghi đè lên một phương thức lớp với một phương pháp mở rộng?

Ví dụ:

public static class StringExtension 
{ 
    public static int GetHashCode(this string inStr) 
    { 
     return MyHash(inStr); 
    } 
} 

Một trường hợp mà tôi đã muốn làm điều này là để có thể lưu trữ một hash của một chuỗi thành một cơ sở dữ liệu và có cùng một giá trị được sử dụng bởi tất cả các lớp học sử dụng hàm băm của chuỗi ký tự (ví dụ: Từ điển, v.v.) Vì thuật toán băm .Net được tích hợp không được đảm bảo tương thích từ một phiên bản của Khung tiếp theo, tôi muốn thay thế bằng phiên bản của riêng mình.

Có trường hợp khác tôi đã chạy vào nơi tôi muốn ghi đè lên một phương pháp lớp với một phương pháp mở rộng cũng vì vậy nó không chỉ cụ thể cho lớp chuỗi hoặc phương pháp GetHashCode.

Tôi biết tôi có thể làm điều này với phân lớp ra khỏi một lớp học hiện có nhưng sẽ thuận tiện để có thể làm điều đó với phần mở rộng trong nhiều trường hợp.

+0

Vì từ điển là cấu trúc dữ liệu trong bộ nhớ , sự khác biệt nào khi thuật toán băm thay đổi từ phiên bản của khung công tác sang khung tiếp theo? Nếu phiên bản khung thay đổi, thì rõ ràng là ứng dụng đã được khởi động lại và từ điển đã được xây dựng lại. –

Trả lời

83

Không; một phương pháp mở rộng không bao giờ được ưu tiên hơn một phương pháp thể hiện với một chữ ký phù hợp, và không bao giờ tham gia vào đa hình (GetHashCode là một phương pháp virtual).

+0

"... không bao giờ tham gia vào đa hình (GetHashCode là một phương pháp ảo)" Bạn có thể giải thích một cách khác tại sao một phương pháp mở rộng sẽ không bao giờ tham gia vào đa hình do nó là ảo? Tôi gặp vấn đề khi thấy kết nối với hai câu lệnh đó. – Alex

+3

@ Alex bằng cách đề cập đến ảo Tôi chỉ đơn giản là làm rõ những gì nó có nghĩa là để được đa hình. Trong hầu như tất cả các ứng dụng của GetHashCode, loại bê tông là không rõ - vì vậy đa hình là trong vở kịch. Do đó, các phương thức mở rộng sẽ không giúp ** ngay cả khi chúng được ưu tiên ** trong trình biên dịch thông thường. Những gì OP thực sự muốn là khỉ vá. Mà C# và .net không tạo điều kiện thuận lợi. –

+3

Điều đó thật đáng buồn, trong C# rất nhiều phương pháp không có ý nghĩa gây hiểu lầm, ví dụ như '.ToString()' trong mảng. Nó chắc chắn là một tính năng cần thiết. –

6

Nếu phương pháp có chữ ký khác, thì có thể thực hiện được - vì vậy trong trường hợp của bạn: không.

Nhưng nếu không bạn cần sử dụng thừa kế để thực hiện những gì bạn đang tìm kiếm.

2

Theo tôi biết câu trả lời là không, bởi vì một phương pháp mở rộng không phải là một thể hiện. Nó giống như một cơ sở intellisense với tôi cho phép bạn gọi một phương thức tĩnh bằng cách sử dụng một thể hiện của một lớp. Tôi nghĩ rằng một giải pháp cho vấn đề của bạn có thể là một kẻ đánh chặn ngăn chặn việc thực hiện một phương pháp cụ thể (ví dụ GetHashCode()) và làm một cái gì đó khác.Để sử dụng một máy đánh chặn (giống như một dự án Castle cung cấp) tất cả các đối tượng cần được instansiated sử dụng một nhà máy đối tượng (hoặc một thùng chứa IoC trong Lâu đài) để các giao diện của họ có thể bị chặn thông qua một proxy động được tạo ra trong thời gian chạy (Caslte cũng cho phép bạn chặn các thành viên ảo của các lớp)

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