In traditional VB, compiled components created a type library that attempted to define what was in the component as far as classes, interfaces, properties, methods, and events. Communication occurred through a binary interface at the COM level. Unfortunately, one language could expect as parameters data types or structures that are not available to other languages, or that are at least difficult to implement. For example, C++ components often expect pointers or structures to be passed in, and this could be problematic if the calling program is written in Visual Basic. The .NET Framework attempts to solve this by compiling additional data into all assemblies. This additional data is called metadata and allows compiled components to interact seamlessly. Couple this with a common type system so that all runtime-compatible languages share the same types, and you can see that cross-language compatibility is enhanced.
The metadata that is stored in the components is binary and contains all types, members, and references in that file or assembly. The metadata is compiled into the PE file, but when the file is used at runtime, the metadata is moved into memory so that it can be accessed more quickly.
One of the most important things to understand is that it is the metadata that allows the runtime to find and execute your code. The metadata is also used by the runtime to create a valid binary native code version when the MSIL is compiled. The runtime also uses metadata to handle the messy details of memory cleanup and security.
When it comes to the benefits of the metadata for a developer, realize that there is so much information in the metadata that you can inherit from a PE created in a different language because the metadata provides such a rich level of detail. This means you are actually inheriting from a compiled component, not an IDL file as was required previously. In fact, because metadata is compiled into the PE or assembly, you no longer need IDL files or type libraries. All the information is now contained in the PE.
By default, the metadata contains the following information:
PE or assembly identity: name, version, culture, public key
Dependencies on other assemblies
Security roles and permissions
Each type has the following metadata:
Name, visibility, base class, implemented interfaces
In addition, you can extend the metadata using attributes. These are created by the developer and allow additional information to be placed in the metadata.