Ответ 1
Монообработка __ComObject
может дать некоторые подсказки. Он действительно объявлен как внутренний, но в комментариях говорится: "У него нет публичных методов, его функциональность отображается через System.Runtime.InteropServices.Marshal
". Я не впал в Marshal
, но я бы предположил, что он отвечает за реализацию GetType()
, поэтому он также может настроить свойство IsPublic
.
По моему опыту Type.GetType("System.__ComObject").IsPublic
всегда true
. Что касается GetType("System.Net.Mail.MSAdminBase")
, я считаю, что это класс COM, открытый через настроенную первичную сборку взаимодействия, где видимость типа может быть явно контролирована (хотя это только мое мышление, никаких исследований не было сделано).
[ОБНОВЛЕНИЕ]
У меня есть последний исходный код Framework и нашел, что я ошибался в своем предположении, что настройка свойства IsPublic
для __ComObject
Тип выполняется с помощью Marshal
. Собственно, это делается неуправляемым кодом. Object.GetType()
определяется внутри Object.cs следующим образом:
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Type GetType();
Неуправляемый исходный код для его реализации в .NET 4.x недоступен, но это доступно для .NET 2.0. Там отличный ответ о реализации Object.GetType
в .NET 2.0. Я бы просто добавил, IsPublic
определяется интерфейсом System.Runtime.InteropServices._Type
, из которого System.Type
происходит и может быть переопределено любым из классов System.Type
-descendent. По-видимому, реализация такого класса возвращается Object.GetType
, и это происходит внутри ObjectNative::GetClass
(sscli20\clr\src\vm\comobject.cpp), как показано в ответе:
if (!objRef->IsThunking())
refType = typeHandle.GetManagedClassObject();
else
refType = CRemotingServices::GetClass(objRef);
Я подтверждаю, что поведение IsPublic
зависит от версии Framework. Я попробовал следующий PowerShell script в разных виртуальных машинах:
Write-Host ([System.Environment]::Version) ([Type]::GetType("System.__ComObject")).IsPublic
Вывод:
2.0.50727.3643 False (WinXP)
4.0.30319.18052 True (Win7)
4.0.30319.19079 True (Win8)
По-видимому, он изменился с False
на true
с .NET 2.0. Я согласен, что true
не соответствует объявлению __ComObject
(internal class __ComObject ...
). Я лично не вижу причин для таких изменений, потому что единственный способ получить экземпляр __ComObject
- через interop.