2012-12-11 19 views
18

Xem ví dụ truyền đơn giản sau đây:Điều gì đó về sự thừa kế/truyền đúc mà tôi không hiểu?

int i = 1000; 
object o = (object)i; // cast 

i.CompareTo(1000); 
o.CompareTo(1000); // error 

Tôi hiểu tại sao dòng cuối cùng lại phát sinh lỗi. Không giống như int, các đối tượng không triển khai IComparable và do đó không hiển thị phương thức CompareTo. Sau đây cũng tạo ra một lỗi:

string s = (string)i; // cast error 

Kể từ khi không có thừa kế giữa ints và chuỗi, đúc sẽ không làm việc ở đây. Bây giờ, hãy xem này:

AudioRender a = new AudioRender(); 
IBaseFilter b = (IBaseFilter)a; // cast 

a.Run(1000); // error 
b.Run(1000); 

(Những lớp học đến từ DirectShowNet library.)

Tôi không hiểu điều này. Các diễn viên không tạo ra một lỗi và ném không có ngoại lệ trong thời gian chạy, vì vậy tôi giả định rằng AudioRender thực hiện IBaseFilter. Tuy nhiên, AudioRender không tiếp xúc với bất kỳ các phương pháp IBaseFilter của, chỉ ra rằng giả định của tôi ở trên là sai ...

Nếu a cụ b, tại sao không a phơi bày các phương pháp b?
Khác, nếu a không triển khai b, tại sao có thể a được đúc thành b?
Ngoài ra, tôi có thể tái tạo hành vi này mà không cần sử dụng DirectShowNet không?

Trả lời

15

Có khả năng AudioRender triển khai Conversion Operator.

Tuy nhiên, sau khi nhìn vào mã có vẻ như rằng cả hai AudioRender và IBaseFilter là Imports Com:

[ComImport, Guid("e30629d1-27e5-11ce-875d-00608cb78066")] 
public class AudioRender { } 


[ComImport, ("56a86895-0ad4-11ce-b03a-0020af0ba770"), 
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
public interface IBaseFilter { .. } 

Như bạn có thể nhìn thấy lớp AudioRender nhập khẩu không thực hiện IBaseFilter, vì vậy bạn sẽ không nhìn thấy nó trong IntelliSense, nhưng có khả năng là đối tượng COM bên dưới triển khai thực hiện nó, do đó tại sao bạn có thể truyền.

+0

Thậm chí nếu có, như thế nào mà trả lời câu hỏi? – Oded

+0

vì nó sẽ cho phép bạn truyền sang loại khác mà không phải là loại cơ sở –

+0

Chắc chắn, nhưng đó không phải là những gì OP đang thấy. OP đang gặp lỗi _unless_ họ truyền. Những gì bạn nói là về việc không cần phải đúc gì cả. – Oded

6

Nếu không nhìn thấy mã nguồn của các loại, tôi nghĩ rằng AudioRender triển khai giao diện IBaseFilterexplicitly, vì vậy bạn sẽ không thấy các phương thức của giao diện trong IntelliSense trên AudioRender.

+0

mã đã được đăng bởi @jarek –

14

Thật khó để nói mà không truy cập vào tài liệu của lớp học AudioRender, nhưng dự đoán hợp lý sẽ là việc triển khai Run trên đó là explicit interface implementation.

public AudioRender : IBaseFilter 
{ 
    IBaseFilter.Run(...) {...} 
} 

Điều đó có nghĩa bạn chỉ có thể truy cập vào các phương pháp Run khi bạn truy cập nó thông qua một tài liệu tham khảo IBaseFilter.

+1

+1 để thực hiện giao diện rõ ràng, tôi không biết rằng có thể trong .NET. Nếu tôi chỉ có thể chấp nhận nhiều câu trả lời. –

2

If a implements b, why doesn't a expose the methods of b?

này có thể đạt được bằng cách implementing explicitly the interfaces

Else, if a does not implement b, why can a be casted to b?

Bởi vì thực sự a thực hiện b.

Also, can I reproduce this behaviour without the use of DirectShowNet?

Có chắc chắn rằng bạn có thể, xem ví dụ này từ liên kết ở trên (obj.Paint() là một lỗi biên dịch):

interface IControl 
    { 
     void Paint(); 
    } 

    public class SampleClass : IControl 
    { 
     void IControl.Paint() 
     { 
      System.Console.WriteLine("IControl.Paint"); 
     } 
    } 

void doit(){ 
    SampleClass obj = new SampleClass(); 
    //obj.Paint(); // Compiler error. 

    IControl c = (IControl)obj; 
    c.Paint(); // Calls IControl.Paint on SampleClass. 
}