C#学习第16天:聊聊反射

发布于:2025-04-19 ⋅ 阅读:(19) ⋅ 点赞:(0)

什么是反射?


  • 定义:反射是一种机制,允许程序在运行时获取关于自身的信息,并且可以动态调用方法、访问属性或创建实例。
  • 用途:常用于框架设计、工具开发、序列化、代码分析和测试等场景

反射的核心概念 


1. 获取类型信息

通过System.Type类,可以获取类型的完整信息。

using System;

public class Example
{
    public void Display()
    {
        Console.WriteLine("Display method called");
    }
}

class Program
{
    static void Main()
    {
        Type type = typeof(Example);
        Console.WriteLine("Methods in Example:");
        
        foreach (var method in type.GetMethods())
        {
            Console.WriteLine(method.Name);
        }
    }
}

2. 动态创建对象

使用Activator.CreateInstance方法在运行时创建对象实例。

Type type = typeof(Example);
object instance = Activator.CreateInstance(type);

MethodInfo displayMethod = type.GetMethod("Display");
displayMethod.Invoke(instance, null);

3. 动态调用方法

可以使用MethodInfo来调用对象的方法。

Type type = typeof(Example);
MethodInfo methodInfo = type.GetMethod("Display");

if (methodInfo != null)
{
    object instance = Activator.CreateInstance(type);
    methodInfo.Invoke(instance, null);
}

4. 访问字段和属性

通过FieldInfoPropertyInfo访问对象的字段和属性。

public class Person
{
    public string Name { get; set; }
    private int age;

    public Person(string name, int age)
    {
        Name = name;
        this.age = age;
    }
}

class Program
{
    static void Main()
    {
        Type personType = typeof(Person);
        var personInstance = Activator.CreateInstance(personType, "Alice", 30);

        PropertyInfo nameProp = personType.GetProperty("Name");
        FieldInfo ageField = personType.GetField("age", BindingFlags.NonPublic | BindingFlags.Instance);

        Console.WriteLine($"Name: {nameProp.GetValue(personInstance)}");
        Console.WriteLine($"Age: {ageField.GetValue(personInstance)}");
    }
}

高级主题


1.反射与特性

反射可用于读取属性(Attribute)信息。

[Obsolete("This class is obsolete.")]
public class OldClass
{
    public void Method() { }
}

class Program
{
    static void Main()
    {
        Type type = typeof(OldClass);
        object[] attributes = type.GetCustomAttributes(false);

        foreach (var attr in attributes)
        {
            Console.WriteLine(attr);
        }
    }
}

2.动态程序集加载(常用)

通过反射可以动态加载程序集并使用其中的类型。

Assembly assembly = Assembly.LoadFrom("SomeLibrary.dll");
Type someType = assembly.GetType("SomeLibrary.SomeClass");

object instance = Activator.CreateInstance(someType);

使用场景


插件系统:

  • 可以动态加载和执行外部模块或插件。

框架设计:

  • ORM框架中,通过反射映射数据库表和类。

工具开发:

  • 提供对象浏览器、自动文档生成等功能。

测试与调试:

  • 在单元测试框架中,反射用于发现和调用测试方法。

实践习题 


编写一个程序,利用反射获取某个类的所有方法名称和参数信息,并打印出来。

using System;
using System.Reflection;

public class SampleClass
{
    public void Method1() { }
    public int Method2(int x) { return x; }
    private string Method3(string input, double value) { return input + value; }
}

class Program
{
    static void Main()
    {
        Type type = typeof(SampleClass);
        
        Console.WriteLine($"Methods in {type.Name}:");

        foreach (MethodInfo method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
        {
            Console.Write($"Method: {method.Name}, Return Type: {method.ReturnType.Name}, Parameters: ");

            ParameterInfo[] parameters = method.GetParameters();
            foreach (var param in parameters)
            {
                Console.Write($"{param.ParameterType.Name} {param.Name} ");
            }
            Console.WriteLine();
        }
    }
}

说明:

  • 使用BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance标志以获取类中的所有公共和私有实例方法。
  • ParameterInfo用于获取每个参数的信息。

 这些示例展示了如何使用反射来动态检查和操作对象,提高代码的灵活性和动态性。如果有其他问题或需要进一步探讨,请随时告诉我!


网站公告

今日签到

点亮在社区的每一天
去签到