Reflection is a powerful feature in .NET that allows you to inspect the metadata of types, methods, properties, and other code elements at runtime. It is part of the System.Reflection namespace and enables developers to access the structure of an assembly (DLL or EXE) without needing to know its exact design at compile time. This makes it useful for scenarios such as:
Reflection enables dynamic type discovery and interaction, which is crucial for creating flexible and extensible applications.
Type ClassThe Type class in System.Reflection represents the metadata of a type. You can use it to get information about a class, interface, struct, enum, or other types in your application.
You can get a Type object by:
typeof(ClassName) for a known class type.GetType() on an object instance to obtain its type.Type:using System;
class Program
{
static void Main()
{
// Using 'typeof' to get the type of the class
Type type = typeof(DemoClass);
Console.WriteLine("Type: " + type.FullName);
// Using 'GetType()' on an instance to get its type
DemoClass demoInstance = new DemoClass();
Type instanceType = demoInstance.GetType();
Console.WriteLine("Instance Type: " + instanceType.FullName);
}
}
public class DemoClass
{
public int Property { get; set; }
public void Method() { }
}
In the above example, both the class type (DemoClass) and an instance's type (demoInstance) are inspected using reflection.
You can use reflection to load an assembly and inspect its types, methods, and other metadata.
using System;
using System.Reflection;
class Program
{
static void Main()
{
// Load the current assembly
Assembly assembly = Assembly.GetExecutingAssembly();
// Get all types in the assembly
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
Console.WriteLine("Type: " + type.FullName);
// Get methods for each type
MethodInfo[] methods = type.GetMethods();
foreach (MethodInfo method in methods)
{
Console.WriteLine(" Method: " + method.Name);
}
}
}
}
In this example, the program loads the current executing assembly and iterates over all types and methods within it using reflection.
You can use reflection to get information about the methods of a class, including the method name, return type, parameters, etc.
using System;
using System.Reflection;
class Program
{
static void Main()
{
Type type = typeof(DemoClass);
// Get all methods of the class
MethodInfo[] methods = type.GetMethods();
foreach (MethodInfo method in methods)
{
Console.WriteLine($"Method: {method.Name}");
foreach (var param in method.GetParameters())
{
Console.WriteLine($" Param: {param.Name}, Type: {param.ParameterType}");
}
}
}
}
public class DemoClass
{
public void Method1(int x, string y) { }
public string Method2() { return "Hello"; }
}
You can also inspect properties and access their values or manipulate them dynamically.
using System;
using System.Reflection;
class Program
{
static void Main()
{
Type type = typeof(DemoClass);
// Get all properties of the class
PropertyInfo[] properties = type.GetProperties();
foreach (PropertyInfo property in properties)
{
Console.WriteLine($"Property: {property.Name}, Type: {property.PropertyType}");
}
}
}
public class DemoClass
{
public int Property1 { get; set; }
public string Property2 { get; set; }
}
Reflection allows you to inspect fields in a class. Fields are variables defined within a class, and you can access or modify their values dynamically.
using System;
using System.Reflection;
class Program
{
static void Main()
{
Type type = typeof(DemoClass);
// Get all fields in the class
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
Console.WriteLine($"Field: {field.Name}, Type: {field.FieldType}");
}
}
}
public class DemoClass
{
public int Field1;
public string Field2;
}
Attributes are used to provide metadata about code elements. Reflection can be used to inspect these attributes at runtime.
using System;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class DocumentationAttribute : Attribute
{
public string Author { get; }
public string Description { get; }
public DocumentationAttribute(string author, string description)
{
Author = author;
Description = description;
}
}
[Documentation("John Doe", "This is a sample class.")]
public class SampleClass
{
[Documentation("Jane Smith", "This is a sample method.")]
public void SampleMethod() { }
}
class Program
{
static void Main()
{
// Get custom attributes for the class
Type type = typeof(SampleClass);
var classAttributes = type.GetCustomAttributes(typeof(DocumentationAttribute), false);
foreach (DocumentationAttribute attr in classAttributes)
{
Console.WriteLine($"Class Author: {attr.Author}, Description: {attr.Description}");
}
// Get custom attributes for the method
var methodInfo = type.GetMethod("SampleMethod");
var methodAttributes = methodInfo.GetCustomAttributes(typeof(DocumentationAttribute), false);
foreach (DocumentationAttribute attr in methodAttributes)
{
Console.WriteLine($"Method Author: {attr.Author}, Description: {attr.Description}");
}
}
}
Reflection also allows you to invoke methods or access properties/fields dynamically, even if you don’t know their names at compile time.
using System;
using System.Reflection;
class Program
{
static void Main()
{
Type type = typeof(DemoClass);
object obj = Activator.CreateInstance(type); // Create an instance dynamically
MethodInfo method = type.GetMethod("SayHello");
method.Invoke(obj, null); // Dynamically invoke method
}
}
public class DemoClass
{
public void SayHello()
{
Console.WriteLine("Hello from dynamically invoked method!");
}
}
In the above code, we create an instance of DemoClass dynamically using Activator.CreateInstance(), and then invoke the SayHello method using reflection.
While powerful, reflection comes with some performance overhead, so it should be used judiciously. Operations like method invocation or property access using reflection are slower than direct method calls or property accesses because of the additional work involved in looking up metadata and dynamically invoking methods.
To improve performance:
MethodInfo, PropertyInfo) if you're going to use them multiple times.System.Reflection namespace and is useful for scenarios like dynamic method invocation, serialization, and creating frameworks.Open this section to load past papers