Подтвердить что ты не робот

Что-то о наследовании/литье .NET, которое я не понимаю?

См. следующий простой пример литья:

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

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

Я понимаю, почему последняя строка генерирует ошибку. В отличие от ints, объекты не реализуют 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.)

Я не понимаю этого. Приведение не генерирует ошибку и не исключает исключений во время выполнения, поэтому я предполагаю, что AudioRender реализует IBaseFilter. Тем не менее, AudioRender не раскрывает ни один из методов IBaseFilter, указывая, что мое предположение выше неверно...

Если a реализует b, почему a не раскрывает методы b?
Else, если a не реализует b, почему a может быть отправлено на b?
Кроме того, могу ли я воспроизвести это поведение без использования DirectShowNet?

4b9b3361

Ответ 1

Вероятно, 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 { .. }

Как вы можете видеть, класс импорта AudioRender не реализует IBaseFilter, поэтому вы не увидите его в intellisense, но вполне вероятно, что базовый COM-объект реализует его, поэтому вы можете использовать.

Ответ 2

Трудно сказать без доступа к документации класса AudioRender, но разумным предположением было бы то, что реализация Run на нем явная реализация интерфейса.

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

Это означает, что вы можете получить доступ только к методу Run при доступе к нему через ссылку IBaseFilter.

Ответ 3

Не видя исходный код типов, я думаю, AudioRender реализует интерфейс IBaseFilter явно, поэтому вы не увидите методов интерфейса в IntelliSense на AudioRender.

Ответ 4

Если a реализует b, почему бы не разоблачить методы b?

это может быть достигнуто с помощью явно реализовать интерфейсы

В противном случае, если a не реализует 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.
}