2012-01-20 32 views
15

Trong Java, bạn có thể mở rộng giao diện với một lớp ẩn danh mà bạn có thể thực hiện khi đang di chuyển. Ví dụ:C# ẩn danh triển khai giao diện (hoặc lớp trừu tượng)

Runnable myRunnable = new Runnable() 
{ 
    @Override 
    public void run() { /**/ } 
} 

(Thông tin thêm về: http://www.techartifact.com/blogs/2009/08/anonymous-classes-in-java.html#ixzz1k07mVIeO)

Đây có phải là có thể trong C#? Nếu không, lựa chọn thay thế khả thi là gì mà không phải dựa vào việc thực hiện rất nhiều lớp con?

Trả lời

14

Không, bạn không thể làm điều đó trong C# - nhưng thường là cách tiếp cận thiết kế thay thế là sử dụng đại biểu thay thế. Trong ví dụ này bạn đã đưa ra, Runnable thường được biểu diễn bằng ThreadStart, và bạn có thể sử dụng một phương pháp hoặc lambda biểu vô danh:

ThreadStart start =() => 
{ 
    // Do stuff here 
}; 

Hoặc nếu bạn chỉ có một phương pháp để chạy, với chữ ký đúng, bạn có thể sử dụng một chuyển đổi nhóm phương pháp:

ThreadStart start = MethodToRunInThread; 

Hoặc trong cuộc gọi Thread constructor:

Thread t = new Thread(MethodToRunInThread); 
t.Start(); 

Nếu bạn thực sự cần phải thực hiện một giao diện, bạn sẽ phải thực sự thực hiện nó (có thể trong một lớp lồng nhau tư nhân). Tuy nhiên, điều đó không xuất hiện thường xuyên trong C#, theo kinh nghiệm của tôi - thường thì các giao diện C# là loại giao diện tự nhiên sẽ yêu cầu thực hiện "thực", ngay cả trong Java.

+1

Đây là tính năng mà tôi bỏ lỡ theo thời gian, đặc biệt là vì giao diện của tôi thường hẹp (giao diện vai trò) và tuân thủ Nguyên tắc phân đoạn giao diện. Nó sẽ thuận tiện khi tôi có thể đăng ký một đại biểu trong cấu hình DI của tôi, trong khi phần còn lại của ứng dụng vẫn có thể phụ thuộc vào giao diện đó (thay vì 'Func '), mà không cần phải tạo một loại lớp proxy nào đó. và triển khai giao diện đó. – Steven

6

Vì Jon đã chỉ ra điều này là không thể trong C#.

Một mẫu thay thế trong C# mặc dù là sử dụng kết hợp giữa nhà máy và đại biểu để cho phép triển khai trên thực tế của giao diện. Về cơ bản, nhà máy lấy một đại diện cho từng phương thức của giao diện và sử dụng chúng như là việc thực hiện sao lưu. Ví dụ: đây là phiên bản dành cho IComparable<T>.

public static class ComparableFactory { 
    private sealed ComparableImpl<T> : IComparable<T> { 
    internal Func<T, T, int> _compareFunc; 
    public int Compare(T left, T right) { 
     return _compareFunc(left, right); 
    } 
    } 
    public IComparable<T> Create<T>(Func<T, T, int> compareFunc) { 
    return new ComparableImpl<T>() { _compareFunc = compareFunc }; 
    } 
} 

... 

IComparable<Person> impl = CompareableFactory.Create<Person>(
    (left, right) => left.Age.CompareTo(right.Age)); 
+0

Rất tuyệt, +1! Nhưng như là một thực hành tốt, tốt hơn là chỉ cần cuộn lớp được đặt tên .. – nawfal

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