Jep*_*sen 20 .net c# reflection encapsulation cil
只是奇怪的是,当我反思所有类型时,我偶然发现了好奇心来检查其他东西.
为什么System.__ComObject集会的阶级mscorlib.dll(有时?)声称是公开的,而事实上它似乎是非公开的?如果我在一个简单的C#控制台应用程序中运行以下代码:
var t = Type.GetType("System.__ComObject");
Console.WriteLine(t.IsPublic); // "True" ?!
Console.WriteLine(t.IsVisible); // "False"
Run Code Online (Sandbox Code Playgroud)
输出似乎有冲突.非嵌套类型(t.IsNested为false)应为IsPublic和提供相同的真值IsVisible.当我看到装配时,IL DASM我看到:
.class private auto ansi beforefieldinit System.__ComObject
extends System.MarshalByRefObject
{
} // end of class System.__ComObject
Run Code Online (Sandbox Code Playgroud)
对我来说,它看起来非常像非公开类,这些对应于下面的C#代码:
namespace System
{
// not public
internal class __ComObject : MarshalByRefObject
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
当我比较其他类型的具有类似的名称,System.__Canon以及类似IL改性剂,既IsPublic与IsVisible预期返回false.
有谁知道为什么(和什么时候)Type.GetType("System.__ComObject").IsPublic给出了真实的?
nos*_*tio 10
Mono的实现的__ComObject可能提供一些线索.它确实被宣布为内部,但评论说"它没有公开的方法,它的功能暴露在低谷System.Runtime.InteropServices.Marshal".我没有挖Marshal,但我认为它负责实施GetType(),所以它也可以定制IsPublic属性.
根据我的经验,Type.GetType("System.__ComObject").IsPublic总是如此true.关于GetType("System.Net.Mail.MSAdminBase"),我相信它是通过定制的主互操作程序集暴露的COM类,其中可以明确控制类型的可见性(虽然这只是我的想法,没有进行过研究).
[UPDATE]
我有最新的Framework源代码,发现我错误地假设我IsPublic的__ComObject类型的属性定制是由Marshal.实际上,它是由非托管代码完成的.Object.GetType()在Object.cs中定义如下:
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Type GetType();
Run Code Online (Sandbox Code Playgroud)
在.NET 4.x中实现它的非托管源代码不可用,但它可用于.NET 2.0.关于.NET 2.0中的实现,有一个很好的答案Object.GetType.我只是添加,IsPublic是由派生定义的System.Runtime.InteropServices._Type接口定义的System.Type,并且可以被任何System.Type-descendent类覆盖.显然,这样的类的实现是通过返回Object.GetType,这是怎么回事内ObjectNative::GetClass(sscli20\CLR\SRC \虚拟机\ comobject.cpp),如图答案:
if (!objRef->IsThunking())
refType = typeHandle.GetManagedClassObject();
else
refType = CRemotingServices::GetClass(objRef);
Run Code Online (Sandbox Code Playgroud)
我确认行为IsPublic取决于Framework版本.我在不同的VM中尝试了以下PowerShell脚本:
Write-Host ([System.Environment]::Version) ([Type]::GetType("System.__ComObject")).IsPublic
Run Code Online (Sandbox Code Playgroud)
输出是:
2.0.50727.3643 False (WinXP)
4.0.30319.18052 True (Win7)
4.0.30319.19079 True (Win8)
Run Code Online (Sandbox Code Playgroud)
显然,它已经从False以True自.NET 2.0.我同意这True与__ComObject(internal class __ComObject ...)的声明不一致.我个人认为没有理由进行这样的改变,因为获得实例的唯一方法__ComObject是通过互操作.
| 归档时间: |
|
| 查看次数: |
2628 次 |
| 最近记录: |