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

时间:2012-12-11 10:13:56

标签: c# .net inheritance interface casting

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

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

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

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

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

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

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的情况下重现此行为吗?

4 个答案:

答案 0 :(得分:15)

AudioRender很可能实现Conversion Operator

然而,看过代码后,似乎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 { .. }

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

答案 1 :(得分:14)

如果不能访问AudioRender类的文档,很难判断,但合理的猜测是Run上的public AudioRender : IBaseFilter { IBaseFilter.Run(...) {...} } 的实现是explicit interface implementation

Run

这意味着您只能在通过IBaseFilter引用访问时访问{{1}}方法。

答案 2 :(得分:6)

如果没有看到类型的源代码,我认为AudioRender实现了接口IBaseFilter explicitly,因此您不会在{{1}上看到IntelliSense中接口的方法}}

答案 3 :(得分:2)

  

如果是一个实现b,为什么不暴露b的方法呢?

这可以通过implementing explicitly the interfaces

来实现
  

否则,如果a没有实现b,为什么可以将b转换为b?

因为a确实实现了b

  

另外,我可以在不使用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.
}