ScholarQuill logoScholarQuillUniversity Notes
  • Notes
  • Past Papers
  • Blogs
  • Todo
Login
ScholarQuill logoScholarQuillUniversity Notes
Login
NotesPast PapersBlogsTodo
More
SubjectsDiscussionCGPA CalculatorGPA CalculatorStudent PortalCourse Outline
About
About usPrivacy PolicyReportContact
Notes
Past Papers
Blogs
Todo
Analytics
    Current Subject
    🧩
    Advanced Programming
    CSI-415
    Progress0 / 55 topics
    Topics
    1. Visual Programming Basics2. Introduction to Events3. Fundamentals of Event-Driven Programming4. Message Handling5. User Interfaces6. Graphics Device Interface7. Painting and Drawing8. Windows Management9. Input Devices10. Resources11. String and Menu Resource12. Dialogs and Windows Controls13. Common Controls14. Dynamic Link Libraries (DLLs)15. Threads and Synchronization16. Network Programming17. Building Class Libraries at the Command Line18. Class Libraries19. Using References20. Assemblies21. Private Assembly Deployment22. Shared Assembly Deployment23. Configuration Overview24. Configuration Files25. Programmatic Access to Configuration26. Using SDK Tools for Signing and Deployment27. Metadata28. Reflection29. Late Binding30. Directories and Files31. Serialization32. Attributes33. Memory Management and Garbage Collection34. Threading and Synchronization35. Asynchronous Delegates36. Application Domains37. Marshal by Value38. Marshal by Reference39. Authentication and Authorization40. Configuring Security41. Code Access Security42. Code Groups43. Evidence44. Permissions45. Role-Based Security46. Principals and Identities47. Using Data Readers48. Using Data Sets49. Interacting with XML Data50. Tracing Event Logs51. Using the Boolean Switch and Trace Switch Classes52. Print Debugging Information with the Debug Class53. Instrumenting Release Builds with the Trace Class54. Using Listeners55. Implementing Custom Listeners
    CSI-415›Reflection
    Advanced ProgrammingTopic 28 of 55

    Reflection

    8 minread
    1,280words
    Intermediatelevel

    Reflection in .NET

    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:

    • Dynamically loading and invoking methods on objects.
    • Inspecting or manipulating types and members.
    • Performing tasks like serialization and deserialization.
    • Creating frameworks that need to work with different types without knowing them at compile time.

    Reflection enables dynamic type discovery and interaction, which is crucial for creating flexible and extensible applications.

    Key Concepts of Reflection

    1. Types: Reflection allows you to inspect the types (classes, interfaces, structs, enums) defined in an assembly.
    2. Members: You can inspect and manipulate the members (methods, properties, fields, events) of these types.
    3. Attributes: Reflection allows you to read the attributes applied to types, methods, and other members.
    4. Dynamic Invocation: You can dynamically invoke methods or access properties at runtime.

    1. Reflection Basics

    A. Using Type Class

    The 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:

    • Using typeof(ClassName) for a known class type.
    • Using GetType() on an object instance to obtain its type.

    Example of Using 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.

    B. Inspecting Assembly Metadata

    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.


    2. Inspecting Members (Methods, Properties, Fields, etc.)

    A. Methods

    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"; }
    }
    

    B. Properties

    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; }
    }
    

    C. Fields

    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;
    }
    

    3. Attributes and Reflection

    Attributes are used to provide metadata about code elements. Reflection can be used to inspect these attributes at runtime.

    Example of Custom Attribute:

    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}");
            }
        }
    }
    

    4. Dynamic Invocation

    Reflection also allows you to invoke methods or access properties/fields dynamically, even if you don’t know their names at compile time.

    Example of Dynamic Method Invocation:

    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.

    5. Use Cases for Reflection

    • Frameworks and Libraries: Reflection is widely used in frameworks such as Entity Framework, ASP.NET Core, Dependency Injection, and more, where types and methods need to be discovered and invoked dynamically.
    • Serialization and Deserialization: Reflection is used in libraries like Newtonsoft.Json to serialize and deserialize objects based on their metadata.
    • Unit Testing: Reflection is useful in testing frameworks for discovering and executing tests dynamically.
    • Plugins and Dynamic Loading: Reflection is useful in applications that support plugins or dynamically loaded assemblies.

    6. Performance Considerations

    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:

    • Cache the reflection results (e.g., MethodInfo, PropertyInfo) if you're going to use them multiple times.
    • Minimize the use of reflection in performance-critical paths.

    Summary

    • Reflection is a feature in .NET that enables inspecting and interacting with types, methods, properties, and other members of assemblies at runtime.
    • It is part of the System.Reflection namespace and is useful for scenarios like dynamic method invocation, serialization, and creating frameworks.
    • With reflection, you can inspect assembly metadata, methods, properties, fields, and custom attributes.
    • Reflection should be used carefully, as it has performance overhead, but it is invaluable for dynamic and flexible applications.
    Previous topic 27
    Metadata
    Next topic 29
    Late Binding

    Past Papers

    Open this section to load past papers

    Click on Show Past Papers to see past papers.
    On This Page
      Reading Stats
      Est. reading time8 min
      Word count1,280
      Code examples0
      DifficultyIntermediate