C# Interview Questions
C# Programming
Web DevelopmentFrontendBackendGame DevQuestion 33
What is reflection in C#?
Answer:
Reflection in C# is a powerful feature that allows a program to inspect and interact with its own metadata and structure at runtime. This includes examining assemblies, modules, types, methods, properties, fields, events, and more. Reflection is part of the System.Reflection
namespace.
Key Concepts of Reflection
-
Metadata Inspection:
- Reflection can be used to retrieve metadata about assemblies, modules, and types.
- It allows you to inspect attributes, access modifiers, and other details.
-
Dynamic Invocation:
- You can dynamically create instances of types, invoke methods, and access fields and properties at runtime.
- This is useful for scenarios such as plugin systems, serialization, and runtime type discovery.
-
Type Information:
- The
Type
class is central to reflection. It represents type declarations for classes, interfaces, arrays, value types, and enumerations.
- The
Basic Usage of Reflection
Getting Type Information
You can obtain type information using the typeof
operator, the GetType
method, or the Type.GetType
method.
Example:
using System;
using System.Reflection;
public class MyClass
{
public void MyMethod()
{
Console.WriteLine("MyMethod invoked");
}
}
public class Program
{
public static void Main()
{
// Using typeof operator
Type type1 = typeof(MyClass);
// Using GetType method
MyClass obj = new MyClass();
Type type2 = obj.GetType();
// Using Type.GetType method
Type type3 = Type.GetType("MyNamespace.MyClass, MyAssembly");
Console.WriteLine(type1.FullName);
Console.WriteLine(type2.FullName);
Console.WriteLine(type3?.FullName);
}
}
Inspecting Members
You can inspect the members of a type, such as methods, properties, fields, and events.
Example:
using System;
using System.Reflection;
public class MyClass
{
public int MyProperty { get; set; }
public void MyMethod() { }
public int MyField;
public event EventHandler MyEvent;
}
public class Program
{
public static void Main()
{
Type type = typeof(MyClass);
Console.WriteLine("Methods:");
MethodInfo[] methods = type.GetMethods();
foreach (var method in methods)
{
Console.WriteLine(method.Name);
}
Console.WriteLine("\nProperties:");
PropertyInfo[] properties = type.GetProperties();
foreach (var property in properties)
{
Console.WriteLine(property.Name);
}
Console.WriteLine("\nFields:");
FieldInfo[] fields = type.GetFields();
foreach (var field in fields)
{
Console.WriteLine(field.Name);
}
Console.WriteLine("\nEvents:");
EventInfo[] events = type.GetEvents();
foreach (var evt in events)
{
Console.WriteLine(evt.Name);
}
}
}
Dynamic Invocation
You can dynamically create instances and invoke methods using reflection.
Example:
using System;
using System.Reflection;
public class MyClass
{
public void MyMethod(string message)
{
Console.WriteLine(message);
}
}
public class Program
{
public static void Main()
{
Type type = typeof(MyClass);
// Creating an instance dynamically
object obj = Activator.CreateInstance(type);
// Invoking a method dynamically
MethodInfo method = type.GetMethod("MyMethod");
method.Invoke(obj, new object[] { "Hello, Reflection!" });
}
}
Accessing Attributes
Reflection allows you to access custom attributes applied to types and members.
Example:
using System;
using System.Reflection;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyCustomAttribute : Attribute
{
public string Description { get; }
public MyCustomAttribute(string description)
{
Description = description;
}
}
[MyCustomAttribute("This is a custom attribute for MyClass")]
public class MyClass
{
[MyCustomAttribute("This is a custom attribute for MyMethod")]
public void MyMethod() { }
}
public class Program
{
public static void Main()
{
Type type = typeof(MyClass);
var classAttribute = (MyCustomAttribute)Attribute.GetCustomAttribute(type, typeof(MyCustomAttribute));
Console.WriteLine($"Class Attribute: {classAttribute.Description}");
MethodInfo method = type.GetMethod("MyMethod");
var methodAttribute = (MyCustomAttribute)Attribute.GetCustomAttribute(method, typeof(MyCustomAttribute));
Console.WriteLine($"Method Attribute: {methodAttribute.Description}");
}
}
Use Cases for Reflection
-
Plugin Systems:
- Load and interact with plugins or assemblies dynamically.
-
Serialization:
- Automatically serialize and deserialize objects by inspecting their properties and fields.
-
Testing Frameworks:
- Discover and run tests dynamically by inspecting methods and attributes.
-
Dependency Injection:
- Dynamically resolve and inject dependencies at runtime.
-
ORM (Object-Relational Mapping):
- Map database records to objects and vice versa by inspecting class structures.
Performance Considerations
While reflection is powerful, it is slower compared to direct method calls and field access due to its dynamic nature. Use reflection judiciously and cache type information when possible to mitigate performance overhead.
Summary
Reflection in C# provides the ability to inspect and interact with the metadata and structure of your code at runtime. It is a powerful tool for dynamic programming, enabling you to create more flexible and extensible applications. By using the System.Reflection
namespace, you can dynamically inspect assemblies, types, members, and attributes, as well as create instances and invoke methods. However, it's important to use reflection judiciously due to its performance overhead.