2012-12-11 39 views
18

請參見下面這個簡單的鑄件例如:關於.NET繼承/鑄造的東西,我不明白?

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

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

我明白爲什麼最後一行產生一個錯誤。與整數不同,對象不執行IComparable,因此不公開CompareTo方法。以下內容也會產生一個錯誤:

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

由於int和string之間沒有繼承關係,所以在這裏鑄造將不起作用。現在,來看看這個:

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

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

這些類來自DirectShowNet library

我不明白這一點。該轉換不會產生錯誤,並且在運行時不會引發異常,所以我假設AudioRender實現了IBaseFilter。然而,AudioRender不公開任何的IBaseFilter的方法,這表明我上面的假設是錯誤的...

如果a工具b,爲什麼不a暴露的b的方法呢?
否則,如果a不執行b,爲什麼a可以被轉換爲b
此外,我可以在不使用DirectShowNet的情況下重現此行爲嗎?

回答

15

AudioRender很可能實現了 Conversion Operator

不過,在看了代碼,似乎AudioRender和IBaseFilter兩者都是COM進口:

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


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

正如你可以看到AudioRender進口類未實現IBaseFilter,所以你不會看到它在智能感知,但底層COM對象很可能會實現它,因此您可以投射。

+0

即使是這樣,請問是怎麼回答問題? – Oded

+0

,因爲它可以讓你投射到另一種類型而不會成爲基礎類型 –

+0

當然,但這不是OP所看到的。 OP正在收到他們投下的錯誤_unless_。你所說的就是根本不需要施放。 – Oded

6

沒有看到類型的源代碼,我認爲AudioRender實現了接口IBaseFilterexplicitly,所以你不會在AudioRender上看到IntelliSense接口的方法。

+0

代碼已經發布的@jarek –

14

如果不訪問AudioRender類的文檔很難說,但合理的猜測是Run的實現是explicit interface implementation

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

這意味着,當您通過IBaseFilter引用訪問它,你只能訪問Run方法。

+1

+1對於顯式接口實現,我不知道在.NET中是可能的。如果只有我可以接受多個答案。 –

2

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

這可以通過implementing explicitly the interfaces

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

因爲確實a實現b來實現。

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

是確保你可以看到這個例子從上面的鏈接(obj.Paint()是一個編譯器錯誤):

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. 
}