C#学习第16天:聊聊反射
什么是反射?
- 定义:反射是一种机制,允许程序在运行时获取关于自身的信息,并且可以动态调用方法、访问属性或创建实例。
- 用途:常用于框架设计、工具开发、序列化、代码分析和测试等场景
反射的核心概念
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. 访问字段和属性
通过FieldInfo和PropertyInfo访问对象的字段和属性。
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用于获取每个参数的信息。
这些示例展示了如何使用反射来动态检查和操作对象,提高代码的灵活性和动态性。如果有其他问题或需要进一步探讨,请随时告诉我!