2009-06-07 52 views
11

如何通過反射來確定對象的類型是由我自己的程序集或.NET Framework中的類定義的?檢測對象的類型是否是由.NET Framework定義的類型

我不想在代碼中提供我自己的程序集的名稱,因爲它應該可以用於任何程序集和名稱空間。

+2

小點 - 但它可能既不是你自己的,也沒有微軟... – 2009-06-07 21:53:02

回答

17

第三方類型在哪裏?您可能想區分聲稱由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<AssemblyCompanyAttribute>() 
        .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; 
} 
+0

並非所有的Microsoft程序集都具有相同的公鑰令牌(即使是現在)。 – 2009-06-07 20:35:26

+0

Ick。將更新答案。 – 2009-06-07 20:58:24

7
obj.GetType().Assembly == System.Reflection.Assembly.GetExecutingAssembly() 

檢查類型是否在當前程序集中聲明。

8

與Mehrdad的答案類似,但即使代碼在某些其他應用程序中執行,也允許進行相同的檢查。

obj.GetType().Assembly == typeof(SomeTypeYouKnowIsInYourAssembly).Assembly 
+0

+1這是一個聰明的做法。 – user7116 2009-06-07 21:12:36

11

基於喬恩的答案,邁赫達德的評論,似乎以下三個值用於公鑰標記(從AssemblyName.FullName ),用於從.NET 2.0和更高.NET Framework提供組件:

公鑰= b77a5c561934e089

  • mscorlib程序
  • System.Data
  • System.Data.OracleClient的
  • System.Data.SqlXml
  • 系統
  • System.Runtime.Remoting
  • System.Transactions的
  • System.Windows.Forms的
  • 系統.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
  • System.Configuration.Install
  • System.Deployment
  • System.Design
  • 的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 。服務
  • 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"); 
    } 
相關問題