2012-05-02 31 views
9

Tôi hy vọng một người nào đó ở đây có thể giải thích những giả định không chính xác mà tôi đang thực hiện. Trong C# 4.0, tôi có 2 giao diện và một lớp thực hiện cả hai. Trong một phương pháp Tôi tuyên bố một biến với các loại hình giao diện đầu tiên, nhanh chóng nó bằng cách sử dụng lớp mà thực hiện cả hai giao diện và bằng cách nào đó có thể đúc nó thành công đến giao diện thứ hai như trong đoạn mã sau:Truyền một giao diện đến giao diện khác mà nó không kế thừa

public interface IFirstInterface 
    { 
     void Method1(); 
    } 

    public interface ISecondInterface 
    { 
     void Method2(); 
    } 

    public class InterfaceImplementation : IFirstInterface, ISecondInterface 
    { 
     public void Method1() { } 
     public void Method2() { } 
    } 

    public class SomeClass 
    { 
     public void SomeMethod() 
     { 
      IFirstInterface first = new InterfaceImplementation(); 
      first.Method1(); 

      // Shouldn't the next line return null? 
      ISecondInterface second = first as ISecondInterface; 
      // second is not null and the call to Method2() works fine 
      second.Method2(); 
     } 
    } 

Tôi cố gắng hiểu tại sao quá trình truyền thành công. Có, lớp thực hiện cả hai giao diện, nhưng tôi nghĩ rằng vì biến đầu tiên được khai báo là IFirstInterface (không kế thừa từ ISecondInterface), nên việc đúc vẫn không thành công.

Tôi cũng đã cố gắng tái cơ cấu mã của mình theo các cách khác, chẳng hạn như không sử dụng 'as', nhưng dàn diễn viên vẫn thành công.

Tôi đang thiếu gì?

Trả lời

7

Từ ví dụ của bạn, bạn nên làm tốt bằng cách kiểm tra loại loại trước khi gọi bất kỳ chức năng nào. Việc tạo đầu tiên sẽ tạo ra một "InterfaceImplementation" đủ điều kiện hỗ trợ cả hai giao diện. Tuy nhiên, bạn đang đặt nó vào một loại được khai báo chỉ là giao diện đầu tiên. Vì vậy, từ quan điểm của đối tượng "đầu tiên", nó chỉ quan tâm đến bất cứ điều gì liên quan đến việc thực hiện IFirstInterface.

Bây giờ, vào thứ hai ... Mặc dù bạn đã tạo đối tượng, bạn vẫn có thể hỏi ... Nhân tiện ... bạn cũng là Giao diện Thứ hai phải không? Nếu có, hãy thực hiện điều này ...

IFirstInterface first = new InterfaceImplementation(); 

if(first is ISecondInterface) 
    // typecast since the second interface is legit, then call it's method 2 
    ((ISecondInterface)first).Method2(); 
+0

Điều này xác nhận những gì tôi nghĩ đã xảy ra. Cảm ơn –

+0

Rất nhiều người cảm ơn, thực sự cần thiết này. +1 (+10 nếu tôi có thể). – Arjang

0

Nếu bạn nhìn từ quan điểm của đối tượng cụ thể, bạn có thể nói "Tôi là một IFirstInterface, nhưng tôi cũng là một ISecondInterface". Đó có phải là ý bạn không? Câu hỏi mà bạn mô tả, sẽ kết thúc bằng việc truyền ngay bên trong một chuỗi kế thừa/triển khai.

1

Điều duy nhất bạn bỏ lỡ là đó chính xác là nó có ý nghĩa như thế nào, và đó là một tính năng hữu ích, không phải là vấn đề. Khi đúc, bạn có thể nghĩ về mã như về cơ bản nói, "Tôi không quan tâm những gì tôi biết loại đối tượng này là, tôi muốn xem nếu nó có thể được chuyển đổi thành loại T". Trong trường hợp này, vì đối tượng bên dưới là loại InterfaceImplementation, bất kể thực tế là nó hiện được gọi là IFirstInterface, câu trả lời là có, nó có thể được chuyển đổi thành một ISecondInterface.

0

Chào mừng bạn đến với đa hình. Đối tượng first luôn là một thể hiện của InterfaceImplementation. Cách bạn chọn tham chiếu nó không ảnh hưởng đến những gì đối tượng thực sự "là". Đây là cách khái niệm trừu tượng hoạt động như một tổng thể.

3

Loại thực tế của cá thể first điểm để triển khai cả hai giao diện. Vì vậy, rõ ràng cả hai Method1Method2 có sẵn trên đối tượng.

Loại tĩnh của first chỉ cho phép bạn truy cập Method1. Loại tĩnh của second chỉ cho phép bạn truy cập Method2. Tôi bạn khai báo một tham chiếu đến đối tượng bằng cách sử dụng một trong hai giao diện, bạn chỉ cần chọn để xem cá thể như một đối tượng thực hiện hợp đồng đã chọn (giao diện).

Khi InterfaceImplementation triển khai cả hai giao diện, bạn có tùy chọn tham chiếu đến cá thể bằng cách sử dụng một trong hai giao diện.

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