The .NET Framework includes an API for examining assembly metadata in the System.Reflection namespace. Rules in early versions of FxCop examined code directly through the reflection API. However, reflection has some limitations that become evident when used in a tool such as FxCop. These limitations primarily stem from the fact that the reflection API is designed to examine programs loaded by the CLR for execution whereas FxCop is charged with inspecting a program that is not about to be executed.
FxCop solves this problem by providing an alternate, similar technology called introspection. The API is similar to reflection but offers generally improved analysis features and is overall more suitable for FxCop than the reflection API. If you liked reflection, you'll love introspection.
The code model divides the metadata into a hierarchy of fundamental primitives known as nodes. Each node is represented by a .NET class in the introspection API that is used to access the relevant metadata attributes. In cases where the node class name would conflict with a .NET Framework class, the API appends the word "Node" to the class name. To keep this list concise, some of the less frequently used node types have been abridged where noted.
Node
AssemblyReference
AttributeNode
Expression
(numerous)
Instruction
Member
EventNode
Field
Method
InstanceInitializer
StaticInitializer
PropertyNode
TypeNode
ClassNode
DelegateNode
EnumNode
InterfaceNode
Struct
(others)
ModuleNode
AssemblyNode
ModuleReference
SecurityAttribute
Statement
(numerous)
![]() | Note |
|---|---|
|
Although .NET assemblies logically contain modules,
|
The introspection model is much deeper than the reflection one. Introspection is capable of drilling down to the statement, expression, and CIL instruction levels, all with rich metadata along the way.
The above shows the "is a" relationships; it is also useful to know the "has a" relationships among the nodes so you can navigate from one node to another.
![]() | Note |
|---|---|
|
Although most of the node types are easily recognized, you might
not be familiar with the terms "instance initializer" and "static
initializer." An instance initializer is just an ordinary "constructor."
A static initializer, also known as a "class constructor," contains code
that initializes fields declared as |