18

See the following simple casting example:

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

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

I understand why the last line generates an error. Unlike ints, objects don't implement IComparable and therefore don't expose the CompareTo method. The following also generates an error:

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

Since there's no inheritance between ints and strings, casting will not work here. Now, take a look at this:

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

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

(These classes come from the DirectShowNet library.)

I don't understand this. The cast does not generate an error and throws no exceptions at runtime, so I assume that AudioRender implements IBaseFilter. However, AudioRender does not expose any of IBaseFilter's methods, indicating that my assumption above is wrong...

If a implements b, why doesn't a expose the methods of b?
Else, if a does not implement b, why can a be casted to b?
Also, can I reproduce this behaviour without the use of DirectShowNet?

Rudey
  • 4,717
  • 4
  • 42
  • 84

4 Answers4

15

It is likely that AudioRender implements Conversion Operator.

However, having looked at code it seems that both AudioRender and IBaseFilter are Com Imports:

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


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

As you can see AudioRender import class does not implement IBaseFilter, so you will not see it in intellisense, but it is likely that underlying COM object implements it, hence why you can cast.

Jarek Kardas
  • 8,445
  • 1
  • 31
  • 32
  • Even if it does, how does that answer the question? – Oded Dec 11 '12 at 10:25
  • because it would allow you to cast to another type without it being a base type – Jarek Kardas Dec 11 '12 at 10:27
  • Sure, but that's not what the OP is seeing. The OP is getting an error _unless_ they cast. What you said is about not needing to cast at all. – Oded Dec 11 '12 at 10:28
  • 1
    Well, if it used explicit cast operator it would require you to cast, but this or the other way, OP is seeing this behavior because both type and interface are COM Imports anyway. – user503386 Dec 11 '12 at 10:31
  • 7
    +1 for actually looking up the types (eventually :)) rather than just speculating. – Rawling Dec 11 '12 at 10:32
14

It is difficult to tell without access to the documentation of the AudioRender class, but a reasonable guess would be that the implementation of Run on it is a explicit interface implementation.

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

That means you can only access the Run method when you access it through a IBaseFilter reference.

Oded
  • 489,969
  • 99
  • 883
  • 1,009
  • 1
    +1 for explicit interface implementation, I did not know that was possible in .NET. If only I could accept multiple answers. – Rudey Dec 11 '12 at 10:49
6

Without seeing the source code of the types, I think AudioRender implements the interface IBaseFilter explicitly, so you won't see the methods of the interface in IntelliSense on AudioRender.

Community
  • 1
  • 1
Jehof
  • 34,674
  • 10
  • 123
  • 155
2

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

this can be achieved by implementing explicitly the interfaces

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

Because indeed a implements b.

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

Yes sure you can, see this example from the above link (obj.Paint() is a compiler error):

    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.
}
Tobia Zambon
  • 7,479
  • 3
  • 37
  • 69