关于.NET继承/转换的一些我不明白的事情?

Rud*_*dey 18 .net c# inheritance casting interface

请参阅以下简单的转换示例:

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

i.CompareTo(1000);
o.CompareTo(1000); // error
Run Code Online (Sandbox Code Playgroud)

我理解为什么最后一行会产生错误.与int不同,对象不实现IComparable,因此不公开该CompareTo方法.以下还会生成错误:

string s = (string)i; // cast error
Run Code Online (Sandbox Code Playgroud)

由于ints和字符串之间没有继承,因此这里的转换不起作用.现在,看看这个:

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

a.Run(1000); // error
b.Run(1000);
Run Code Online (Sandbox Code Playgroud)

(这些类来自DirectShowNet库.)

我不明白这一点.强制转换不会生成错误,并且在运行时不会抛出任何异常,因此我假设AudioRender实现了IBaseFilter.但是,AudioRender没有暴露任何IBaseFilter的方法,表明我的上述假设是错误的......

如果a实现b,为什么不a公开方法b
否则,如果a没有实施b,为什么可以a投入b
此外,我可以在不使用DirectShowNet的情况下重现此行为吗?

Jar*_*das 15

AudioRender很可能实现了转换运算符.

但是,看过代码后,似乎AudioRender和IBaseFilter都是Com Imports:

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


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

正如您所看到的,AudioRender导入类没有实现IBaseFilter,因此您不会在intellisense中看到它,但很可能底层COM对象实现它,因此您可以进行强制转换.

  • +1实际上查找类型(最终:))而不仅仅是推测. (7认同)

Ode*_*ded 14

没有访问AudioRender类的文档很难说,但合理的猜测是它的实现Run是一个显式的接口实现.

public AudioRender : IBaseFilter
{
  IBaseFilter.Run(...) {...}
}
Run Code Online (Sandbox Code Playgroud)

这意味着您只能在Run通过IBaseFilter引用访问该方法时访问该方法.


Jeh*_*hof 6

在没有看到类型的源代码的情况下,我认为显式地AudioRender实现了接口,因此您不会在IntelliSense上看到接口的方法.IBaseFilter AudioRender