Во-первых, пример чего-то, что работает как ожидалось: (весь код был выполнен в непосредственном окне VS2008),
25 is IComparable
>> true
25.GetType().GetInterfaces()
>> {System.Type[5]}
>> [0]: {Name = "IComparable" FullName = ...
>> [1]: {Name = "IFormattable" FullName = ...
>> ...
Пока неплохо. Теперь давайте примерим объект, где интерфейс наследован через базовый тип:
class TestBase : IComparable
{
public int CompareTo(object obj) { throw new NotImplementedException(); }
}
class TheTest : TestBase { }
В непосредственном окне:
(new TheTest()) is IComparable
>> true
(new TheTest()).GetType().GetInterfaces()
>> {System.Type[1]}
>> [0]: {Name = "IComparable" FullName = "System.IComparable"}
Никакие неожиданности здесь также. Каким образом следующий код не показывает интерфейсов тогда:
wcfChannel = ChannelFactory<IMyServiceApi>.CreateChannel(binding, endpointAddress);
wcfChannel is IMyServiceApi && wcfChannel is ICommunicationObject
>> true
typeof(IMyServiceApi).IsInterface && typeof(ICommunicationObject).IsInterface
>> true
wcfChannel.GetType().GetInterfaces()
>> {System.Type[0]}
Как все вышеупомянутое может быть верным одновременно?
(редактирование: добавленный wcfChannel is ICommunicationObject
выше, который является в это время, необъясненное ответом, который объясняет как wcfChannel is IMyServiceApi
верно.)
Это потому, что типом wcfChannel
является сам интерфейс:
>> channel.GetType().FullName
"MyService.IMyServiceApi"
>> channel.GetType().IsInterface
true
>> channel.GetType() == typeof(IMyServiceApi)
true
.GetInterfaces ()
возвращает только интерфейсы унаследован или реализован , но не сам интерфейс.
По общему признанию, экземпляр объекта обычно имеет интерфейсный тип, но, как вы упомянули в своем комментарии к вопросу, объект на самом деле является прозрачным прокси. Для этого прокси-сервера имеет смысл не зависеть от фактической реализации интерфейса и заботиться только об интерфейсе. Тот факт, что .GetType ()
возвращает интерфейс, делает прокси максимально прозрачным.