- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
当我出于好奇而反射(reflection)所有类型以检查其他内容时,我偶然发现了一个奇怪的现象。
为什么程序集 mscorlib.dll
(有时?)的类 System.__ComObject
声称是公开的,而实际上它似乎是非公开的?如果我在一个简单的 C# 控制台应用程序中运行以下代码:
var t = Type.GetType("System.__ComObject");
Console.WriteLine(t.IsPublic); // "True" ?!
Console.WriteLine(t.IsVisible); // "False"
输出似乎是矛盾的。非嵌套类型(t.IsNested
为假)应该为 IsPublic
和 IsVisible
提供相同的真值。当我使用 IL DASM
查看程序集时,我看到:
.class private auto ansi beforefieldinit System.__ComObject
extends System.MarshalByRefObject
{
} // end of class System.__ComObject
在我看来,它看起来很像一个非公共(public)类,对应于下面的 C# 代码:
namespace System
{
// not public
internal class __ComObject : MarshalByRefObject
{
...
}
}
当我与另一个具有相似名称 System.__Canon
和相似 IL 修饰符的类型进行比较时,IsPublic
和 IsVisible
都返回如预期的那样错误。
有谁知道为什么(以及何时)Type.GetType("System.__ComObject").IsPublic
给出 true?
最佳答案
Mono's implementation __ComObject
可能会提供一些线索。它确实被声明为 internal,但评论说 “它没有公共(public)方法,它的功能通过 System.Runtime.InteropServices.Marshal
公开”。我没有深入研究 Marshal
,但我认为它负责 GetType()
的实现,因此它可以自定义 IsPublic
属性也是。
根据我的经验,Type.GetType("System.__ComObject").IsPublic
始终是 true
。关于 GetType("System.Net.Mail.MSAdminBase")
,我相信它是通过 customized primary interop assembly 公开的 COM 类,其中可以显式控制类型的可见性(尽管这只是我的想法,尚未进行任何研究)。
[更新]
我有 latest Framework source code并发现我错误地假设 __ComObject
类型的 IsPublic
属性的自定义是由 Marshal
完成的。实际上,它是由非托管代码完成的。 Object.GetType()
在 Object.cs 中定义如下:
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Type GetType();
其在 .NET 4.x 中实现的非托管源代码不可用,但它是 available对于.NET 2.0。有一个 excellent answer关于 .NET 2.0 中的 Object.GetType
实现。我只想补充一点,IsPublic
由 System.Runtime.InteropServices._Type
接口(interface)定义,System.Type
派生自该接口(interface),并且可以被覆盖通过任何 System.Type
-descendent 类。显然,此类的实现由 Object.GetType
返回,并且发生在 ObjectNative::GetClass
(sscli20\clr\src\vm\comobject.cpp) 中,如图the answer :
if (!objRef->IsThunking())
refType = typeHandle.GetManagedClassObject();
else
refType = CRemotingServices::GetClass(objRef);
我确认 IsPublic
的行为取决于框架版本。我在不同的虚拟机中尝试了以下 PowerShell 脚本:
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)
显然,自 .NET 2.0 以来,它已从 False
更改为 True
。我同意 True
与 __ComObject
(internal class __ComObject ...
)的声明不一致。我个人认为没有理由进行这种更改,因为获取 __ComObject
实例的唯一方法是通过互操作。
关于c# - 为什么类型 System.__ComObject 声称(有时)是公开的,而实际上不是?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18090412/
我正在优化我们用来查询 Active Directory 的一些代码。其中一种方法获取自特定更新以来已更改的所有 AD 用户,由目录条目的 uSNCreated 属性确定。本质上,它是在执行 C# 等
是否可以将 System.__ComObject 转换为仅在运行时才知道的某种类型?我有以下代码 Type ComClassType = SomeDLLAssembly.GetType("ClassN
我正在使用 DSOFile 从某些 Crystal Reports 报表文件中获取摘要属性。 SummaryProperties.Thumbnail 返回一个对象,我需要将该对象转换为图像,以便在我的
由于将项目从 VS2010 升级到 VS2012,我收到错误消息: 'System.__ComObject' does not contain a definition for .WithComCle
Powershell与Excel新手在这里。我正在学习如何通过 powershell 与 excel 交互,并在几个网站上发现了“范围”功能。 奇怪的是,此功能在我的系统上不起作用并返回以下错误:方法
我有一个涉及以下场景的问题,应用程序 A 有一个 DataGridView,从中选择对象。它们被拖到应用程序 B 内的 DataGridView 中,对象被复制到新列表中。这是 App A 中的代码,
我正在尝试使用反射将 System.__ComObject 转换为接口(interface)类型。我试过使用 Convert.ChangeType(Object,Type) 但是 c# 然后抛出这个错
我将是第一个承认这是过时的编程。我以前从来没有看过AD,真的不明白。我想那是我的下一个研究...... 无论如何,这是一些测试代码,它应该显示到期日期——要么是可读的,要么是刻度线——这无关紧要。 (
尝试在 Visual Studio 2010 中发布 XNA 项目时出现以下错误。 Error 1 Publish failed with the following error: Unable to
我正在使用 C# 与 SolidWorks 交互。 我使用的是 Visual Studio 2017 最新版本 (15.7.3)。该项目引用了 SolidWorks .tlb 文件,就像文档中所说的那
我正在尝试自动登录并从特定站点收集数据。这是我的代码 $ie = New-Object -ComObject InternetExplorer.Application; $ie.Visible = $
我一直在编写一个使用网络浏览器界面运行某些服务器功能的脚本。我使用 Internet Explorer 8 在 Windows 7 上编写了脚本,它运行良好。一旦我将它移动到运行 Windows 20
这是我用来读取 xls 文件的代码: Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Intero
我正在尝试将以下 C# 代码转换为 PowerShell(我省略了我认为不相关的代码部分): C# System.Type t = System.Type.GetTypeFromProgID("Vis
有人知道在 C# 中对 __ComObject 实例使用“动态”关键字时是否有办法防止 RuntimeBinder 中的内存泄漏吗? 我得到了以下代码: var t = Type.GetTypeFro
我有两个 C# 项目,一个是 dll,另一个是 Windows 窗体应用程序。 我在 dll 中定义了一个 CoClass,如下所示` ' [ComVisible(true), Gui
我正在尝试使用 LINQPad快速发展小ArcObjects (一个基于 COM 的库,用于 ESRI's ArcGIS 软件)应用程序,并在使用它来 Dump() 我从 .NET 初始化的 COM
当我出于好奇而反射(reflection)所有类型以检查其他内容时,我偶然发现了一个奇怪的现象。 为什么程序集 mscorlib.dll(有时?)的类 System.__ComObject 声称是公开
我编写了一个使用防火墙 COM 库 Interop.NetFwTypeLib 来管理 TCP 传输规则的 Windows 服务。在两台机器上部署不报告问题,但我最近在另一台计算机上安装它并收到异常:
下面的代码给了我错误:cannot convert COM object of type 'System.__ComObject' to class type 'System.Web.UI.WebCo
我是一名优秀的程序员,十分优秀!