检测对象的类型是否为.NET Framework定义的类型
如何通过reflection确定对象的类型是由我自己的程序集中的类还是由.NET Framework定义的?
我不想在代码中提供我自己的程序集的名称,因为它应该适用于任何程序集和命名空间。
第三方类型会在哪里进入? 您可能希望区分声称由Microsoft提供的类型和不提供的类型。
using System; using System.Linq; using System.Reflection; class Test { static void Main() { Console.WriteLine(IsMicrosoftType(typeof(string))); Console.WriteLine(IsMicrosoftType(typeof(Test))); } static bool IsMicrosoftType(Type type) { object[] attrs = type.Assembly.GetCustomAttributes (typeof(AssemblyCompanyAttribute), false); return attrs.OfType() .Any(attr => attr.Company == "Microsoft Corporation"); } }
当然,根据这个方案,任何类型都可以声称是微软的,但如果你实际上只是在你自己的类型和框架上调用它,我怀疑这应该工作正常。
或者,您可以使用程序集的公钥令牌。 这可能更难伪造。 它依赖于微软为所有程序集使用通用公钥,但他们没有(根据Mehrdad在下面的评论)。 但是,您可以轻松地将此解决方案用于一组接受的“这是来自Microsoft”公钥。 或许以某种方式结合这两种方法并报告任何差异以便进一步检查……
static bool IsMicrosoftType(Type type) { AssemblyName name = type.Assembly.GetName(); byte[] publicKeyToken = name.GetPublicKeyToken(); return publicKeyToken != null && publicKeyToken.Length == 8 && publicKeyToken[0] == 0xb7 && publicKeyToken[1] == 0x7a && publicKeyToken[2] == 0x5c && publicKeyToken[3] == 0x56 && publicKeyToken[4] == 0x19 && publicKeyToken[5] == 0x34 && publicKeyToken[6] == 0xe0 && publicKeyToken[7] == 0x89; }
根据Jon的回答和Mehrdad的评论,似乎以下三个值用于.NET Framework提供的.NET 2.0及更高版本的程序集的公钥令牌(来自AssemblyName.FullName):
公钥= b77a5c561934e089
- mscorlib程序
- System.Data
- System.Data.OracleClient的
- System.Data.SqlXml
- 系统
- System.Runtime.Remoting
- System.Transactions的
- System.Windows.Forms的
- 的System.Xml
- SMDiagnostics
- System.Runtime.Serialization
- System.ServiceModel
- System.ServiceModel.Install
- System.ServiceModel.WasHosting
公钥= b03f5f7f11d50a3a
- 无障碍
- AspNetMMCExt
- cscompmgd
- CustomMarshalers
- IEExecRemote
- IEHost
- IIEHost
- ISymWrapper
- Microsoft.Build.Conversion
- Microsoft.Build.Engine
- Microsoft.Build.Framework
- Microsoft.Build.Tasks
- Microsoft.Build.Utilities
- Microsoft.JScript程序
- Microsoft.VisualBasic.Compatibility.Data
- Microsoft.VisualBasic.Compatibility
- Microsoft.VisualBasic程序
- Microsoft.VisualBasic.Vsa
- Microsoft.VisualC
- Microsoft.Vsa
- Microsoft.Vsa.Vb.CodeDOMProcessor
- Microsoft_VsaVb
- sysglobl
- 系统配置
- System.Configuration.Install
- System.Deployment
- 系统设计
- 的System.DirectoryServices
- System.DirectoryServices.Protocols
- System.Drawing.Design
- System.Drawing中
- 的System.EnterpriseServices
- 系统管理
- System.Messaging
- System.Runtime.Serialization.Formatters.Soap
- System.Security
- System.ServiceProcess
- 的System.Web
- System.Web.Mobile
- System.Web.RegularExpressions
- System.Web.Services
- Microsoft.Transactions.Bridge
- Microsoft.Transactions.Bridge.Dtc
- Microsoft.Build.Tasks.v3.5
- Microsoft.CompactFramework.Build.Tasks
- Microsoft.Data.Entity.Build.Tasks
- Microsoft.VisualC.STLCLR
- Sentinel.v3.5Client
公钥= 31bf3856ad364e35
- PresentationCFFRasterizer
- PresentationUI
这是从以下代码生成的:
private void PrintAssemblyInfo(string fullName) { string[] parts = fullName.Split(','); Console.WriteLine(" - {0}, {1}", parts[0], parts[3]); } private void GenerateInfo(string path) { foreach (var file in Directory.GetFiles(path, "*.dll", SearchOption.AllDirectories)) { try { Assembly assembly = Assembly.ReflectionOnlyLoadFrom(file); PrintAssemblyInfo(assembly.GetName().FullName); } catch { } } } private void GenerateInfo() { GenerateInfo(@"C:\Windows\Microsoft.NET\Framework\v2.0.50727"); GenerateInfo(@"C:\Windows\Microsoft.NET\Framework\v3.0"); GenerateInfo(@"C:\Windows\Microsoft.NET\Framework\v3.5"); }
与Mehrdad的答案类似,但即使代码在某些其他应用程序中执行,也允许进行相同的检查。
obj.GetType().Assembly == typeof(SomeTypeYouKnowIsInYourAssembly).Assembly
obj.GetType().Assembly == System.Reflection.Assembly.GetExecutingAssembly()
检查是否在当前程序集中声明了类型。