反射的一些时间






4.57/5 (4投票s)
一篇解释 .NET 反射 API 中一些有价值方面的文章
引言
本文将重点介绍 .NET Framework 的反射 API。反射文档通常包含特性和编写动态代码,但我将避免后者,并尝试解释使用反射的一些更重要的方面,尽管它可能在编写实际应用程序中没有价值。相反,它确实有价值,并且精通它的人将能够使用反射来编写开发工具,甚至能够编写可以减少堆消耗的程序。为了初学者的重要理解,某些部分将逐步讲解一些源代码,以便掌握 C# 语法,但(在我有限的知识范围内)这篇文章可能接近中级水平。反射通常用于确定程序集定义了哪些类型。框架类库提供了许多获取此信息的方法,但最常用的方法是 Assembly 的 GetExportedTypes
。下面是一些加载程序集并显示其中所有公共导出的类型名称的示例源代码。在解释了一些基本知识之后,输出将出现在下一节中。请检查此代码,然后我们将查看 Assembly 类的方法、属性和 static
方法。
using System;
using System.Reflection;
public static class Program {
public static void Main() {
String dataAssembly = "System.Data, version=4.0.0.0, " +
"culture=neutral, PublicKeyToken=b77a5c561934e089";
LoadAssemAndShowPublicTypes(dataAssembly);
}
private static void LoadAssemAndShowPublicTypes(String assemId) {
Assembly a = Assembly.Load(assemId);
foreach (Type t in a.GetExportedTypes()) {
Console.WriteLine(t.FullName);
}
}
}
Assembly 类静态方法
GetAssembly
GetCallingAssembly
GetEntryAssembly
GetExecutingAssembly
Load (加载)
LoadFile
LoadFrom
ReflectionOnlyLoad
ReflectionOnlyLoadFrom
如您所见,GetExportedTypes
方法不是 static
的。请检查 Assembly 类的属性
EntryPoint
FullName
GlobalAssemblyCache
Location
ReflectionOnly
此时,检查语法非常重要。请检查此程序
using System;
using System.Reflection;
class Program {
static void Main(string[] area)
{
string path = @"C:\windows\Microsoft.net\Framework\v2.0.50727\System.dll";
Assembly a = Assembly.LoadFile(path);
ShowAssemblyInfo(a);
Assembly ourAssembly = Assembly.GetExecutingAssembly();
ShowAssemblyInfo(ourAssembly);
Console.Read();
}
static void ShowAssemblyInfo(Assembly a)
{
Console.WriteLine(a.FullName);
Console.WriteLine("From GAC? {0}", a.GlobalAssemblyCache);
Console.WriteLine("Path: {0}", a.Location);
Console.WriteLine("Version: {0}", a.ImageRuntimeVersion);
foreach (Module m in a.GetModules())
{
Console.WriteLine(" Mod: {0}", m.Name);
}
Console.WriteLine();
}
}
输出如下
c:\Windows\Microsoft.NET\Framework\v4.0.30319>getmod
System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
From GAC? True
Path: C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c
561934e089\System.dll
Version: v4.0.30319
Mod: System.dll
GetMod, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
From GAC? False
Path: c:\Windows\Microsoft.NET\Framework\v4.0.30319\GetMod.exe
Version: v4.0.30319
Mod: GetMod.exe
代码首先声明一个 string
string path = @"C:\windows\Microsoft.net\Framework\v2.0.50727\System.dll";
引用的 string
被存储在赋给 string
对象的“path
”值中,因此“path
”存储了左侧引号中包含的目录路径(其中包含要加载的程序集)。下一行代码实例化 Assembly
类。这被设置为等于 Assembly
类的 static
方法 LoadFile
。请注意,此方法将上述路径(存储 string
的值)作为参数传递。另请注意,“a
”后面紧跟着 Assembly 现在存储了该程序集的路径,因为它已被加载
Assembly a = Assembly.LoadFile(path);
此时,我们编写一个 static
方法来显示有关当前加载程序集的信息。由于它正在执行,我们实例化另一个 Assembly
类的实例。static
方法 ShowAssemblyInfo
实现了它的名称所示的功能。初学者需要注意,原始值“a
”作为传递给参数的 string
路径的引用,通过点语法写入以显示属性:(a.Location
, a.GlobalAssemblyCache
, a.FullName
等等。)以下是 Assembly 类的一些非 static
方法
CreateInstance
GetCustomAttributes
GetExportedTypes
GetModule
GetModules
GetTypes
话虽如此,让我们来看看原始源代码的输出。为简洁起见,请注意这些是(将近一半的)public
导出的类型
System.Text.RegularExpressions.Regex
System.Text.RegularExpressions.MatchEvaluator
System.Text.RegularExpressions.Capture
System.Text.RegularExpressions.CaptureCollection
System.Text.RegularExpressions.RegexCompilationInfo
System.Text.RegularExpressions.Group
System.Text.RegularExpressions.GroupCollection
System.Text.RegularExpressions.RegexRunner
System.Text.RegularExpressions.Match
System.Text.RegularExpressions.MatchCollection
System.Text.RegularExpressions.RegexOptions
System.Text.RegularExpressions.RegexRunnerFactory
System.CodeDom.CodeObject
System.CodeDom.CodeExpression
System.CodeDom.CodeArgumentReferenceExpression
System.CodeDom.CodeArrayCreateExpression
System.CodeDom.CodeArrayIndexerExpression
System.CodeDom.CodeStatement
System.CodeDom.CodeAssignStatement
System.CodeDom.CodeAttachEventStatement
System.CodeDom.CodeAttributeArgument
System.CodeDom.CodeAttributeArgumentCollection
System.CodeDom.CodeAttributeDeclaration
System.CodeDom.CodeAttributeDeclarationCollection
System.CodeDom.CodeBaseReferenceExpression
System.CodeDom.CodeBinaryOperatorExpression
System.CodeDom.CodeBinaryOperatorType
System.CodeDom.CodeCastExpression
System.CodeDom.CodeCatchClause
System.CodeDom.CodeCatchClauseCollection
System.CodeDom.CodeDirective
System.CodeDom.CodeChecksumPragma
System.CodeDom.CodeComment
System.CodeDom.CodeCommentStatement
System.CodeDom.CodeCommentStatementCollection
System.CodeDom.CodeCompileUnit
System.CodeDom.CodeConditionStatement
System.CodeDom.CodeTypeMember
System.CodeDom.CodeMemberMethod
System.CodeDom.CodeConstructor
System.CodeDom.CodeDefaultValueExpression
System.CodeDom.CodeDelegateCreateExpression
System.CodeDom.CodeDelegateInvokeExpression
System.CodeDom.CodeDirectionExpression
System.CodeDom.CodeDirectiveCollection
System.CodeDom.CodeEntryPointMethod
System.CodeDom.CodeEventReferenceExpression
System.CodeDom.CodeExpressionCollection
System.CodeDom.CodeExpressionStatement
System.CodeDom.CodeFieldReferenceExpression
System.CodeDom.CodeGotoStatement
System.CodeDom.CodeIndexerExpression
System.CodeDom.CodeIterationStatement
System.CodeDom.CodeLabeledStatement
System.CodeDom.CodeLinePragma
System.CodeDom.CodeMemberEvent
System.CodeDom.CodeMemberField
System.Net.FileWebResponse
System.Net.FtpStatusCode
……… etc ………………
System.Net.NetworkInformation.NetworkInterface
System.Net.NetworkInformation.NetworkInterfaceComponent
System.Net.NetworkInformation.NetBiosNodeType
System.Net.NetworkInformation.OperationalStatus
System.Net.NetworkInformation.PhysicalAddress
System.Net.NetworkInformation.PingCompletedEventHandler
System.Net.NetworkInformation.PingCompletedEventArgs
System.Net.NetworkInformation.Ping
System.Net.NetworkInformation.PingException
System.Net.NetworkInformation.PingOptions
System.Net.NetworkInformation.PingReply
System.Net.NetworkInformation.PrefixOrigin
System.Net.NetworkInformation.SuffixOrigin
System.Net.NetworkInformation.TcpConnectionInformation
System.Net.NetworkInformation.TcpStatistics
System.Net.NetworkInformation.UdpStatistics
System.Net.NetworkInformation.TcpState
System.Net.Configuration.AuthenticationModuleElement
System.Net.Configuration.AuthenticationModuleElementCollection
System.Net.Configuration.AuthenticationModulesSection
System.Net.Configuration.BypassElement
System.Net.Configuration.BypassElementCollection
System.Net.Configuration.ConnectionManagementElement
System.Net.Configuration.ConnectionManagementElementCollection
System.Net.Configuration.ConnectionManagementSection
System.Net.Configuration.DefaultProxySection
System.Net.Configuration.HttpWebRequestElement
System.Net.Configuration.HttpListenerElement
System.Net.Configuration.HttpCachePolicyElement
System.Net.Configuration.FtpCachePolicyElement
System.Net.Configuration.Ipv6Element
System.Net.Configuration.MailSettingsSectionGroup
System.Net.Configuration.ModuleElement
System.Net.Configuration.NetSectionGroup
System.Net.Configuration.PerformanceCountersElement
System.Net.Configuration.ProxyElement
System.Net.Configuration.ProxyElement+BypassOnLocalValues
System.Net.Configuration.ProxyElement+UseSystemDefaultValues
System.Net.Configuration.ProxyElement+AutoDetectValues
System.Net.Configuration.RequestCachingSection
System.Configuration.SchemeSettingElement
System.Configuration.SchemeSettingElementCollection
System.Net.Configuration.SettingsSection
System.Net.Configuration.ServicePointManagerElement
System.Net.Configuration.SmtpSection
System.Net.Configuration.SmtpNetworkElement
System.Net.Configuration.SmtpSpecifiedPickupDirectoryElement
System.Net.Configuration.SocketElement
…..etc….
System.Diagnostics.FileVersionInfo
System.Diagnostics.ICollectData
System.Diagnostics.InstanceData
System.Diagnostics.InstanceDataCollection
System.Diagnostics.InstanceDataCollectionCollection
System.Diagnostics.MonitoringDescriptionAttribute
System.Diagnostics.OverflowAction
System.Diagnostics.PerformanceCounter
System.Diagnostics.PerformanceCounterCategory
System.Diagnostics.PerformanceCounterCategoryType
System.Diagnostics.PerformanceCounterInstanceLifetime
System.Diagnostics.PerformanceCounterManager
System.Diagnostics.PerformanceCounterPermission
System.Diagnostics.PerformanceCounterPermissionAccess
System.Diagnostics.PerformanceCounterPermissionAttribute
System.Diagnostics.PerformanceCounterPermissionEntry
System.Diagnostics.PerformanceCounterPermissionEntryCollection
System.Diagnostics.PerformanceCounterType
System.Diagnostics.Process
System.Diagnostics.ProcessModule
System.Diagnostics.ProcessModuleCollection
System.Diagnostics.ProcessPriorityClass
System.Diagnostics.ProcessStartInfo
System.Diagnostics.ProcessThread
System.Diagnostics.ProcessThreadCollection
System.Diagnostics.ProcessWindowStyle
System.Diagnostics.Stopwatch
System.Diagnostics.ThreadPriorityLevel
System.Diagnostics.ThreadState
System.Diagnostics.ThreadWaitReason
System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverageAttribute
System.Configuration.AppSettingsReader
System.IO.Ports.Handshake
System.IO.Ports.Parity
System.IO.Ports.SerialError
System.IO.Ports.SerialErrorReceivedEventArgs
System.IO.Ports.SerialErrorReceivedEventHandler
System.IO.Ports.SerialPinChange
System.IO.Ports.SerialPinChangedEventArgs
System.IO.Ports.SerialPinChangedEventHandler
System.IO.Ports.SerialPort
System.IO.Ports.SerialData
System.IO.Ports.SerialDataReceivedEventArgs
System.IO.Ports.SerialDataReceivedEventHandler
System.IO.Ports.StopBits
那个对象是什么类型?
或者,什么是 Type 对象?众所周知,.NET 中的所有对象都派生自 System.Object。该根命名空间中定义的方法之一是 GetType。请注意,前面的代码迭代了一个 System.Type 对象数组。System.Type 类型是进行类型和对象操作的起点。System.Type 是一个抽象基类型,派生自 System.Reflection.MemberInfo(因为一个 Type 可以是另一个类型的成员)。FCL 提供了几种派生自 System.Type 的类型:System.RuntimeType、System.ReflectionOnlyType、System.Reflection.TypeDelegator,以及 System.Reflection.Emit 命名空间中定义的一些类型(EnumBuilder、GenericTypeParameterBuilder 和 TypeBuilder)。Object 类支持的 GetType 方法返回一个 Type 对象,该对象引用对象的实际 Type。例如,让我们创建一个 Animal 类,然后创建两个派生自 Animal 类的类
using System;
public class Animal
{
}
public class Dog : Animal
{
}
public class Cat : Animal
{
}
class App {
static void Main() {
Animal aAnim = new Animal();
Animal aDog = new Dog();
Animal aCat = new Cat();
Console.WriteLine("Typename for aAnim is {0}", aAnim.GetType().Name);
Console.WriteLine("Typename for aDog is {0}", aDog.GetType().Name);
Console.WriteLine("Typename for aCat is {0}", aCat.GetType().Name);
}
}
输出符合预期。请注意“typeof
”关键字的使用
Typename for aAnim is Animal
Typename for aDog is Dog
Typename for aCat is Cat
要为泛型类型构造实例,首先获取对开放类型的引用,然后调用 Type 的 public
实例 MakeGenericType
方法,并传入要用作类型参数的类型数组。然后,获取返回的 Type
对象,并将其传递给上面列出的各种方法之一。这是一个例子
using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
internal sealed class Dictionary { }
public static class Program {
public static void Main()
{
Type openType = typeof(Dictionary<,>);
Type closedType = openType.MakeGenericType(typeof(String),
typeof(Int32)); Object o = Activator.CreateInstance(closedType);
Console.WriteLine(o.GetType());
}
}
编译此代码时,应得到以下结果
Dictionary`2[System.String,System.Int32]
使用反射发现类型的成员
根据微软的技术文档,发现和调用类型成员的能力通常用于创建开发人员工具和实用程序,这些工具和实用程序通过查找特定编程模式或成员的使用来分析程序集。执行此操作的工具/实用程序的示例包括 ILDasm.exe、FxCopCmd.exe 以及 Visual Studio 的 Windows Forms 和 Web 设计器。
字段、构造函数、方法、属性、事件和嵌套类型都可以定义为类型内的成员。FCL 包含一个名为 System.Reflection.MemberInfo
的类型。此类是抽象基类,封装了所有类型成员共有的许多属性。从 MemberInfo
派生出来的是一堆类;每个类都封装了与特定类型成员相关的更多属性。下面是这些类型的分层列表
System.Object
System.Reflection.MemberInfo
System.Type
System.Reflection.FieldInfo
System.Reflection.MethodBase
System.Reflection.ContructorInfo
System.Reflection.MethodInfo
System.Reflection.PropertyInfo
System.Reflection.EventInfo
对于每种类型,都会调用 GetMembers
方法,并返回一个 MemberInfo
派生对象的数组;每个对象都引用类型中定义的单个成员。传递给 GetMembers
方法的 BindingFlags
变量 bf
告诉方法返回哪些类型的成员。然后,对于每个成员,将显示其类型(字段、构造函数、方法、属性等)及其 string
值(通过调用 ToString
获取)。BindingFlags
主题稍后将进行讨论。请研究此代码
using System;
using System.Reflection;
public static class Program {
public static void Main() {
// Loop through all assemblies loaded in this AppDomain
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly a in assemblies) {
WriteLine(0, "Assembly: {0}", a);
// Find Types in the assembly
foreach (Type t in a.GetExportedTypes()) {
WriteLine(1, "Type: {0}", t);
// Discover the type's members
const BindingFlags bf = BindingFlags.DeclaredOnly |
BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Instance | BindingFlags.Static;
foreach (MemberInfo mi in t.GetMembers(bf)) {
String typeName = String.Empty;
if (mi is Type) typeName = "(Nested) Type";
else if (mi is FieldInfo) typeName = "FieldInfo";
else if (mi is MethodInfo) typeName = "MethodInfo";
else if (mi is ConstructorInfo) typeName = "ConstructoInfo";
else if (mi is PropertyInfo) typeName = "PropertyInfo";
else if (mi is EventInfo) typeName = "EventInfo";
WriteLine(2, "{0}: {1}", typeName, mi);
}
}
}
}
private static void WriteLine(Int32 indent, String format, params Object[] args) {
Console.WriteLine(new String(' ', 3 * indent) + format, args);
}
}
编译的代码运行时会输出大量信息。这是输出的一小部分示例,请尝试与分层列表建立联系。
Assembly: mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Type: System.Object
MethodInfo: System.String ToString()
MethodInfo: Boolean Equals(System.Object)
MethodInfo: Boolean Equals(System.Object, System.Object)
MethodInfo: Boolean ReferenceEquals(System.Object, System.Object)
MethodInfo: Int32 GetHashCode()
MethodInfo: System.Type GetType()
MethodInfo: Void Finalize()
MethodInfo: System.Object MemberwiseClone()
MethodInfo: Void FieldSetter(System.String, System.String, System.Object)
MethodInfo: Void FieldGetter(System.String, System.String, System.Object ByRef)
MethodInfo: System.Reflection.FieldInfo GetFieldInfo(System.String, System.String)
ConstructoInfo: Void .ctor()
Type: System.Runtime.Serialization.ISerializable
MethodInfo: Void GetObjectData(System.Runtime.Serialization.SerializationInfo,
System.Runtime.Serialization.StreamingContext)
Type: System.Runtime.InteropServices._Exception
MethodInfo: System.String ToString()
MethodInfo: Boolean Equals(System.Object)
MethodInfo: Int32 GetHashCode()
MethodInfo: System.Type GetType()
MethodInfo: System.String get_Message()
MethodInfo: System.Exception GetBaseException()
MethodInfo: System.String get_StackTrace()
MethodInfo: System.String get_HelpLink()
MethodInfo: Void set_HelpLink(System.String)
MethodInfo: System.String get_Source()
MethodInfo: Void set_Source(System.String)
MethodInfo: Void GetObjectData(System.Runtime.Serialization.SerializationInfo,
System.Runtime.Serialization.StreamingContext)
MethodInfo: System.Exception get_InnerException()
MethodInfo: System.Reflection.MethodBase get_TargetSite()
PropertyInfo: System.String Message
PropertyInfo: System.String StackTrace
PropertyInfo: System.String HelpLink
PropertyInfo: System.String Source
PropertyInfo: System.Exception InnerException
PropertyInfo: System.Reflection.MethodBase TargetSite
Type: System.Exception
MethodInfo: System.String get_Message()
MethodInfo: System.Collections.IDictionary get_Data()
MethodInfo: System.Exception GetBaseException()
MethodInfo: System.Exception get_InnerException()
MethodInfo: System.Reflection.MethodBase get_TargetSite()
MethodInfo: System.Reflection.MethodBase GetTargetSiteInternal()
MethodInfo: System.String get_StackTrace()
MethodInfo: System.String GetStackTrace(Boolean)
MethodInfo: Void SetErrorCode(Int32)
MethodInfo: System.String get_HelpLink()
MethodInfo: Void set_HelpLink(System.String)
MethodInfo: System.String get_Source()
MethodInfo: Void set_Source(System.String)
MethodInfo: System.String ToString()
MethodInfo: System.String ToString(Boolean)
MethodInfo: Void add_SerializeObjectState
(System.EventHandler`1[System.Runtime.Serialization.SafeSerializationEventArgs])
MethodInfo: Void remove_SerializeObjectState
(System.EventHandler`1[System.Runtime.Serialization.SafeSerializationEventArgs])
MethodInfo: Void GetObjectData
(System.Runtime.Serialization.SerializationInfo,
System.Runtime.Serialization.StreamingContext)
MethodInfo: System.Exception PrepForRemoting()
MethodInfo: Void InternalPreserveStackTrace()
MethodInfo: Int32 get_HResult()
MethodInfo: Void set_HResult(Int32)
MethodInfo: System.String InternalToString()
MethodInfo: System.Type GetType()
MethodInfo: Boolean get_IsTransient()
MethodInfo: System.String GetMessageFromNativeResources(ExceptionMessageKind)
MethodInfo: Void Init()
MethodInfo: Boolean IsImmutableAgileException(System.Exception)
MethodInfo: System.String GetClassName()
MethodInfo: System.IRuntimeMethodInfo GetMethodFromStackTrace(System.Object)
MethodInfo: System.Reflection.MethodBase GetExceptionMethodFromStackTrace()
MethodInfo: System.String GetExceptionMethodString()
MethodInfo: System.Reflection.MethodBase GetExceptionMethodFromString()
MethodInfo: Void OnDeserialized(System.Runtime.Serialization.StreamingContext)
MethodInfo: Boolean nIsTransient(Int32)
MethodInfo: Void GetMessageFromNativeResources
(ExceptionMessageKind, System.Runtime.CompilerServices.StringHandleOnStack)
ConstructoInfo: Void .ctor()
ConstructoInfo: Void .ctor(System.String)
ConstructoInfo: Void .ctor(System.String, System.Exception)
ConstructoInfo: Void .ctor
(System.Runtime.Serialization.SerializationInfo,
System.Runtime.Serialization.StreamingContext)
PropertyInfo: System.String Message
PropertyInfo: System.Collections.IDictionary Data
PropertyInfo: System.Exception InnerException
PropertyInfo: System.Reflection.MethodBase TargetSite
PropertyInfo: System.String StackTrace
PropertyInfo: System.String HelpLink
PropertyInfo: System.String Source
PropertyInfo: Int32 HResult
PropertyInfo: Boolean IsTransient
EventInfo: System.EventHandler`1
[System.Runtime.Serialization.SafeSerializationEventArgs] SerializeObjectState
FieldInfo: System.String _className
FieldInfo: System.Reflection.MethodBase _exceptionMethod
FieldInfo: System.String _exceptionMethodString
FieldInfo: System.String _message
FieldInfo: System.Collections.IDictionary _data
FieldInfo: System.Exception _innerException
FieldInfo: System.String _helpURL
FieldInfo: System.Object _stackTrace
FieldInfo: System.Object _watsonBuckets
FieldInfo: System.String _stackTraceString
FieldInfo: System.String _remoteStackTraceString
FieldInfo: Int32 _remoteStackIndex
FieldInfo: System.Object _dynamicMethods
FieldInfo: Int32 _HResult
FieldInfo: System.String _source
FieldInfo: IntPtr _xptrs
FieldInfo: Int32 _xcode
FieldInfo: UIntPtr _ipForWatsonBuckets
FieldInfo: System.Runtime.Serialization.SafeSerializationManager
_safeSerializationManager
FieldInfo: Int32 _COMPlusExceptionCode
(Nested) Type: System.Exception+ExceptionMessageKind
Type: System.ValueType
MethodInfo: Boolean Equals(System.Object)
MethodInfo: Int32 GetHashCode()
MethodInfo: Int32 GetHashCodeOfPtr(IntPtr)
MethodInfo: System.String ToString()
MethodInfo: Boolean CanCompareBits(System.Object)
MethodInfo: Boolean FastEqualsCheck(System.Object, System.Object)
ConstructoInfo: Void .ctor()
使用 BindingFlags
BindingFlags
枚举用于控制如何使用 GetMembers
方法检索类型的成员,以及每个成员类型的特定成员。更确切地说,BindingFlags
会过滤返回的成员类型。您可以通过调用 Type 的 GetMembers
、GetNestedTypes
、GetFields
、GetConstructors
、GetMethods
、GetProperties
或 GetEvents
方法来查询类型的成员。调用这些方法中的任何一个时,都可以传递 System.Reflection.BindingFlags
枚举类型的实例。该枚举类型标识了一组位标志,这些标志通过 OR 运算组合在一起,以帮助您过滤从这些方法返回的成员。尽管我们在最后一个示例中使用了 BindingFlags
,但这是例证其直接目的的源代码
using System;
using System.Reflection;
public class Program
{
public static void Main(string[] args)
{
string path = @"C:\Windows\Microsoft.NET\Framework\v2.0.50727\" +
"System.ServiceProcess.dll";
// using BindingFlags to only get the declared
// and instance members
BindingFlags flags =
BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Instance;
Assembly a = Assembly.LoadFrom(path);
Console.WriteLine(a.FullName);
Type[] types = a.GetTypes();
foreach ( Type t in types )
{
Console.WriteLine(" Type: {0}", t.Name);
MemberInfo[] m = t.GetMembers(flags);
foreach (MemberInfo member in m)
{
Console.WriteLine(" {0}: {1}", member.MemberType, member.Name);
}
}
Console.Read();
}
}
当我们运行编译后的代码时,我们将看到(和往常一样,有很多信息).NET 使用 API 返回信息类型,这些类型接受 BindingFlags
标志式枚举值来将搜索限制在具有某些属性的抽象上
System.ServiceProcess, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
Type: NativeMethods
NestedType: SERVICE_STATUS
NestedType: ServiceMainCallback
NestedType: ServiceControlCallback
NestedType: ServiceControlCallbackEx
NestedType: StructFormat
NestedType: ENUM_SERVICE_STATUS
NestedType: ENUM_SERVICE_STATUS_PROCESS
NestedType: QUERY_SERVICE_CONFIG
NestedType: SERVICE_TABLE_ENTRY
NestedType: LSA_UNICODE_STRING
NestedType: LSA_UNICODE_STRING_withPointer
NestedType: LSA_OBJECT_ATTRIBUTES
NestedType: SERVICE_DESCRIPTION
NestedType: SERVICE_DELAYED_AUTOSTART_INFO
NestedType: SERVICE_FAILURE_ACTIONS
NestedType: SC_ACTION
NestedType: WTSSESSION_NOTIFICATION
Type: SERVICE_STATUS
Field: serviceType
Field: currentState
Field: controlsAccepted
Field: win32ExitCode
Field: serviceSpecificExitCode
Field: checkPoint
Field: waitHint
Type: ServiceMainCallback
Method: Invoke
Method: BeginInvoke
Method: EndInvoke
Constructor: .ctor
Type: ServiceControlCallback
Method: Invoke
Method: BeginInvoke
Method: EndInvoke
Constructor: .ctor
Type: ServiceControlCallbackEx
Method: Invoke
Method: BeginInvoke
Method: EndInvoke
Constructor: .ctor
Type: PowerBroadcastStatus
Field: value__
Type: SafeNativeMethods
Type: ServiceAccount
Field: value__
Type: ServiceBase
Method: RequestAdditionalTime
Method: get_AutoLog
Method: set_AutoLog
Method: get_ExitCode
Method: set_ExitCode
Method: get_CanHandlePowerEvent
Method: set_CanHandlePowerEvent
Method: get_CanHandleSessionChangeEvent
Method: set_CanHandleSessionChangeEvent
Method: get_CanPauseAndContinue
Method: set_CanPauseAndContinue
Method: get_CanShutdown
Method: set_CanShutdown
Method: get_CanStop
Method: set_CanStop
Method: get_EventLog
Method: get_ServiceName
Method: set_ServiceName
Method: Stop
Method: ServiceMainCallback
Constructor: .ctor
Property: AutoLog
Property: ExitCode
Property: CanHandlePowerEvent
Property: CanHandleSessionChangeEvent
Property: CanPauseAndContinue
Property: CanShutdown
Property: CanStop
Property: EventLog
Property: ServiceName
Type: ServiceController
Method: get_CanPauseAndContinue
Method: get_CanShutdown
Method: get_CanStop
Method: get_DisplayName
Method: set_DisplayName
Method: get_DependentServices
Method: get_MachineName
Method: set_MachineName
Method: get_ServiceName
Method: set_ServiceName
Method: get_ServicesDependedOn
Method: get_ServiceHandle
Method: get_Status
Method: get_ServiceType
Method: Close
Method: Pause
Method: Continue
Method: ExecuteCommand
Method: Refresh
Method: Start
Method: Start
Method: Stop
Method: WaitForStatus
Method: WaitForStatus
Constructor: .ctor
Constructor: .ctor
Constructor: .ctor
Property: CanPauseAndContinue
Property: CanShutdown
Property: CanStop
Property: DisplayName
Property: DependentServices
Property: MachineName
Property: ServiceName
Property: ServicesDependedOn
Property: ServiceHandle
Property: Status
Property: ServiceType
Type: ServiceControllerPermission
Method: get_PermissionEntries
Constructor: .ctor
Constructor: .ctor
Constructor: .ctor
Constructor: .ctor
Property: PermissionEntries
Type: ServiceControllerPermissionAccess
Field: value__
Type: ServiceControllerPermissionAttribute
Method: get_MachineName
Method: set_MachineName
Method: get_PermissionAccess
Method: set_PermissionAccess
Method: get_ServiceName
Method: set_ServiceName
Method: CreatePermission
Constructor: .ctor
Property: MachineName
Property: PermissionAccess
Property: ServiceName
Type: ServiceControllerPermissionEntry
Method: get_MachineName
Method: get_PermissionAccess
Method: get_ServiceName
Constructor: .ctor
Constructor: .ctor
Property: MachineName
Property: PermissionAccess
Property: ServiceName
Type: ServiceControllerPermissionEntryCollection
Method: get_Item
Method: set_Item
Method: Add
Method: AddRange
Method: AddRange
Method: Contains
Method: CopyTo
Method: IndexOf
Method: Insert
Method: Remove
Property: Item
Type: ServiceControllerStatus
Field: value__
Type: ServiceInstaller
Method: get_DisplayName
Method: set_DisplayName
Method: get_Description
Method: set_Description
Method: get_ServicesDependedOn
Method: set_ServicesDependedOn
Method: get_ServiceName
Method: set_ServiceName
Method: get_StartType
Method: set_StartType
Method: get_DelayedAutoStart
Method: set_DelayedAutoStart
Method: CopyFromComponent
Method: Install
Method: IsEquivalentInstaller
Method: Rollback
Method: Uninstall
Constructor: .ctor
Property: DisplayName
Property: Description
Property: ServicesDependedOn
Property: ServiceName
Property: StartType
Property: DelayedAutoStart
Type: ServiceProcessDescriptionAttribute
Method: get_Description
Constructor: .ctor
Property: Description
Type: ServiceProcessInstaller
Method: get_HelpText
Method: get_Password
Method: set_Password
Method: get_Account
Method: set_Account
Method: get_Username
Method: set_Username
Method: CopyFromComponent
Method: Install
Method: Rollback
Constructor: .ctor
Property: HelpText
Property: Password
Property: Account
Property: Username
Type: ServiceStartMode
Field: value__
Type: ServiceType
Field: value__
Type: SessionChangeReason
Field: value__
Type: SessionChangeDescription
Method: get_Reason
Method: get_SessionId
Method: Equals
Method: GetHashCode
Method: Equals
Property: Reason
Property: SessionId
Type: TimeoutException
Constructor: .ctor
Constructor: .ctor
Constructor: .ctor
Type: ServiceInstallerDialogResult
Field: value__
Type: ServiceInstallerDialog
Method: get_Password
Method: set_Password
Method: get_Result
Method: get_Username
Method: set_Username
Constructor: .ctor
Property: Password
Property: Result
Property: Username
Type: FXAssembly
Type: ThisAssembly
Type: AssemblyRef
Type: ResDescriptionAttribute
Method: get_Description
Constructor: .ctor
Property: Description
Type: ResCategoryAttribute
Constructor: .ctor
Type: Res
Type: ExternDll
Type: HResults
Type: StructFormat
Field: value__
Type: ENUM_SERVICE_STATUS
Constructor: .ctor
Field: serviceName
Field: displayName
Field: serviceType
Field: currentState
Field: controlsAccepted
Field: win32ExitCode
Field: serviceSpecificExitCode
Field: checkPoint
Field: waitHint
Type: ENUM_SERVICE_STATUS_PROCESS
Constructor: .ctor
Field: serviceName
Field: displayName
Field: serviceType
Field: currentState
Field: controlsAccepted
Field: win32ExitCode
Field: serviceSpecificExitCode
Field: checkPoint
Field: waitHint
Field: processID
Field: serviceFlags
Type: QUERY_SERVICE_CONFIG
Constructor: .ctor
Field: dwServiceType
Field: dwStartType
Field: dwErrorControl
Field: lpBinaryPathName
Field: lpLoadOrderGroup
Field: dwTagId
Field: lpDependencies
Field: lpServiceStartName
Field: lpDisplayName
Type: SERVICE_TABLE_ENTRY
Constructor: .ctor
Field: name
Field: callback
Type: LSA_UNICODE_STRING
Constructor: .ctor
Field: length
Field: maximumLength
Field: buffer
Type: LSA_UNICODE_STRING_withPointer
Constructor: .ctor
Field: length
Field: maximumLength
Field: pwstr
Type: LSA_OBJECT_ATTRIBUTES
Constructor: .ctor
Field: length
Field: rootDirectory
Field: pointerLsaString
Field: attributes
Field: pointerSecurityDescriptor
Field: pointerSecurityQualityOfService
Type: SERVICE_DESCRIPTION
Field: description
Type: SERVICE_DELAYED_AUTOSTART_INFO
Field: fDelayedAutostart
Type: SERVICE_FAILURE_ACTIONS
Field: dwResetPeriod
Field: rebootMsg
Field: command
Field: numActions
Field: actions
Type: SC_ACTION
Field: type
Field: delay
Type: WTSSESSION_NOTIFICATION
Constructor: .ctor
Field: size
Field: sessionId
Type: SafeServiceHandle
Type: DeferredHandlerDelegate
Method: Invoke
Method: BeginInvoke
Method: EndInvoke
Constructor: .ctor
Type: DeferredHandlerDelegateCommand
Method: Invoke
Method: BeginInvoke
Method: EndInvoke
Constructor: .ctor
Type: DeferredHandlerDelegateAdvanced
Method: Invoke
Method: BeginInvoke
Method: EndInvoke
Constructor: .ctor
Type: UnsafeNativeMethods
Type: ServiceNameConverter
Method: CanConvertFrom
Method: ConvertFrom
Method: GetStandardValues
Method: GetStandardValuesExclusive
Method: GetStandardValuesSupported
Constructor: .ctor
总之,请记住,C# 编译器会发出元数据和 IL 代码。元数据存储在一堆表中。构建程序集或模块时,使用的编译器会创建一个类型定义表、字段定义表、方法定义表等。System.Reflection
命名空间包含几种类型,允许您编写代码来反射(或解析)这些元数据表。实际上,此命名空间中的类型提供了对程序集或模块中包含的元数据的对象模型。使用这些对象模型类型,您可以轻松地枚举类型定义元数据表中的所有类型。然后,对于每种类型,您可以获取其基类型、它实现的接口以及与该类型关联的标志。System.Reflection
命名空间中的其他类型允许您通过解析相应的元数据表来查询类型的字段、方法、属性和事件。如果您想编写一个可以使用的程序集,请转储一个程序集并研究其信息。一个非常有用的工具正是用于此目的,名为 .NET Reflector。
参考文献
- Joe Duffy 著《Professional .NET Framework 2.0》
历史
- 2010 年 8 月 27 日:初次发布