Metadata of types. Purpose and features of use. The need for metadata. Ways to get type information
Contents
- 1. What is type metadata? An example demonstrating the need to use type metadata
- 2. Types described by metadata
- 3. Ways to get type information
- 4. Getting information about the type using the System.Object.GetType() method. Example
- 5. Getting information about a type using the typeof() operator. Example
- 6. Retrieving type information using the System.Type.GetType() method. Example
- Related topics
Search other websites:
1. What is type metadata? An example demonstrating the need to use type metadata
After a program is written in C#, it is compiled. The compilation creates an assembly that is the base unit of .NET. An assembly means a file with the *.dll or *.exe extension. Each assembly you create has parts. One of the components of the assembly is the so-called metadata, with the help of which the types that have been defined in the program are described. For example, if the program implements a class named MyClass, then it is considered that this type is MyClass, and this type is described by metadata in the compiled assembly.
Metadata types are widely used in communication between programs. The following uses of type metadata can be listed:
- serialization of objects;
- distributed applications;
- remote work;
- XML services;
- interlanguage interaction in the IDE;
- other uses.
Figure 1 shows an example of the use of metadata in the case of distributed applications. The case of combining computers into a local network and their interaction is considered. Let the server host mathematical software that contains the corresponding functionality. From one or more client computers, a request is made to the server to carry out calculations, for example, solving a quadratic equation. The server receives the request, performs the calculations, and returns the result to the client.
In order for the client and server to interact with each other, a common assembly is required. In our case, this is the assembly ClassLibrary1.dll. The assembly contains information about the CalcEquation() method for calculating a quadratic equation. The client and server use the assembly metadata to obtain information about the content of the assembly (types, method names, method parameters, etc.). The assembly metadata is accessed using a reflection mechanism.
Figure 1. Communication between client and server using co-assembly metadata
⇑
2. Types described by metadata
In C# .NET, the following types are described using metadata:
- classes (class)
- interfaces (interface)
- structures (struct)
- enumerations (enum)
- delegates (delegate).
⇑
3. Ways to get type information
Type information can be obtained in the following ways:
- using the ildasm.exe utility. The ildasm.exe utility uses reflection to access assembly items by reading type metadata. More details about the operation of the ildasm.exe utility are described here;
- programmatically.
To get metadata programmatically, you can use one of three methods:
- use the System.Object.GetType() method. This method allows you to define the metadata of an object;
- use the typeof() operator. This method allows you to define type information without creating an object;
- use the System.Type.GetType() method. This method allows you to determine information about a type based on its name (string representation) using metadata.
The first two methods to programmatically obtain metadata implement an early binding mechanism. With this kind of binding, the type information is known in the program at compile time.
The third method (using the System.Type.GetType() method) implements the late binding mechanism. In the case of late binding, the type information is unknown at compile time. The compiler contains generic type definition code based on what is called reflection. More details about the features of the use of reflection are described here.
⇑
4. Getting information about the type using the System.Object.GetType() method. Example
As you know, the base class for all classes in .NET is the class object or System.Object. To get metadata of types using the tools of the System.Object class, the GetType() method is used, which has the following general form:
public System.Type GetType();
In the simplest case, the System.Object.GetType() method is applied to an instance of the class according to the following pattern
MyClass mc = new MyClass(); Type tp = mc.GetType();
The result is a tp instance of type Type. This instance contains all the necessary information about the type MyClass.
Example. The example demonstrates the use of the reflection mechanism for the Complex class. The so-called early binding is implemented.
Let the Complex class be given, which has the following elements:
- internal fields re, im;
- constructors without parameters and with two parameters;
- properties Re and Im for accessing the internal fields of the class;
- methods Add(), Sub() that implement operations of addition and subtraction of complex numbers;
- the Print() method displays information about the number.
using System; using System.Reflection; namespace ConsoleApp15 { // A class that implements operations on complex numbers class Complex { // Public fields private double re, im; // Constructors public Complex(double _re, double _im) { re = _re; im = _im; } public Complex() : this(0, 0) { } // Properties public double Re { get { return re; } set { re = value; } } public double Im { get { return im; } set { im = value; } } // Methods public Complex Add(double re2, double im2) { return new Complex(re + re2, im + im2); } public Complex Sub(double re2, double im2) { return new Complex(re - re2, im - im2); } public void Print(string text) { Console.Write(text); Console.Write("{0:f2}", re); if (im > 0) Console.Write("+"); Console.WriteLine("{0:f2}*j", im); } } class Program { static void Main(string[] args) { // Get information about the types of the Complex class // using System.Object.GetType() // 1. Declare an instance of the Complex class Complex cm = new Complex(5, 8); // 2. Get the type from the instance Type tp = cm.GetType(); // method GetType() of class Object // 3. Get a list of methods of the Complex class // Select methods according to the following criteria: // - only public-methods; // - only from an instance; // - only those methods that are declared in the Complex class. MethodInfo[] mi = tp.GetMethods( BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly ); // 4. Display the names of the methods of the Complex class foreach (MethodInfo m in mi) { Console.WriteLine("{0}", m.Name); } Console.ReadKey(); } } }
The result of the program
get_Re set_Re get_Im set_Im Add Sub Print
As you can see from the result, not only the names of the methods are displayed, but also the names of the methods associated with the properties Re and Im of the class. To select separately the Add(), Sub(), Print() methods, you need to get a list of properties, then in a loop form a new set of methods without property names. This is another topic.
⇑
5. Getting information about a type using the typeof() operator. Example
You can get information about a type using the typeof() operator, which has the following general form:
typeof(SomeType)
where SomeType is some type.
In the simplest case, to determine information about the type of MyClass, using typeof() can be, for example, like this
class MyClass { // ... } ... Type tp = typeof(MyClass);
The result is a tp instance of type System.Type that contains information about the MyClass class.
More details on using the typeof() operator are described here.
Example. On the example of the Complex class (see the previous example), a list of constructors of this class is obtained. Below is the abbreviated code for solving the task.
using System; using System.Reflection; ... // A class that implements operations on complex numbers class Complex { ... } ... static void Main(string[] args) { // Get information about the types of the Complex class using typeof() // 1. Get an instance of System.Type from the Complex class Type tp = typeof(Complex); // 2. Get a list of the Complex class constructors ConstructorInfo[] ci = tp.GetConstructors(); // 4. Print a list of constructors with parameters foreach (ConstructorInfo c in ci) { Console.Write(c.Name + "("); // Generate a list of constructor parameters ParameterInfo[] pi = c.GetParameters(); for (int i = 0; i < pi.Length; i++) { Console.Write("{0} {1}", pi[i].ParameterType.Name, pi[i].Name); if (i < pi.Length - 1) Console.Write(", "); } Console.WriteLine(")"); } Console.ReadKey(); } ...
The result of the program
.ctor(Double _re, Double _im) .ctor()
⇑
6. Retrieving type information using the System.Type.GetType() method. Example
The GetType() method of the System.Type class allows you to get information about a type based on its name as a string of type System.String. This method of obtaining type information is used in the so-called late binding.
Late binding is a technique of creating and calling an instance of a certain type (for example, a class) during program execution without first connecting it at compile time. With late binding, the type name is obtained as a string. Then, based on this string, an instance of the System.Type is formed. More details about the specifics of the late binding implementation are described here.
The GetType() method has several overloaded implementations, one of which has the following general form
public static System.Type GetType(string typeName);
here
- typeName – the name of the type to get information about. Note that the string is of type System.String.
Example. Suppose the program needs to get information about the Triangle type of another assembly MyConsoleApp. The type and assembly information is unknown at compile time. Only the assembly name (MyConsoleApp) and the type name (Triangle) are known.
The following snippet demonstrates how to use the System.Type.GetType() method to get information about the type of a Triangle. The fragment gets a list of attributes of the Triangle class.
using System; using System.Reflection; ... // 1. Load the assembly Assembly asm = Assembly.Load("MyConsoleApp"); // 2. Get the type from assembly Type tp = asm.GetType("MyConsoleApp.Triangle"); // 3. Get attributes of class MyClass2 object[] objs = tp.GetCustomAttributes(true); // 4. Display attribute names on screen foreach (object obj in objs) { Console.WriteLine(obj.GetType().Name); } ...
⇑
Related topics
- Reflection of types. Getting type metadata. The System.Reflection namespace. Class System.Type. Ways to get information about types. Operator typeof
- Examples of obtaining information about methods, interfaces, classes, structures, enumerations, delegates, type fields, method parameters, type statistics
- Dynamically loadable assemblies. Class Assembly. Methods Load() and LoadFrom()
- Late binding. Method call. Example. Class System.Activator. Method Invoke()
- Examples of using the reflection based on late binding
⇑