Что-то о наследовании/литье .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?
Ответы
Ответ 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.
}