什么是反射?
反射就是动态发现类型信息的能力。它帮助程序设计人员在程序运行时利用一些信息去动态地使用类型,这些信息在设计时是未知的,这种能力类似于后期绑定。反射还支持的更高级的行为,能在运行时动态创建新类型,并且对这些新类型的操作进行调用。
听起来可能不太清楚,那反射有什么用呢?
可能还是不太清楚,那下面就通过一个简单的例子来介绍一下:
自定义一个类和特性:
[AttributeUsage(AttributeTargets.Method)]
public class ApiAttribute : Attribute
{
public string name;
public ApiAttribute(string _name)
{
name = _name;
}
}
public class lwpoor
{
private int password;
public string name;
public lwpoor()
{
}
public lwpoor(string name)
{
this.name = name;
}
[Api("测试 test")]
public string test(string username)
{
return username;
}
public string test1(string username)
{
return username;
}
}
使用反射调用自定义类:
static void Main(string[] args)
{
Console.WriteLine("Hello, World!");
var type = typeof(lwpoor);
//获取所有公共属性
var pro = type.GetFields();
foreach (var prop in pro)
{
Console.WriteLine($"属性名称:{prop.Name} 类型:{prop.FieldType.Name}");
}
//获取类中标注ApiAttribute特性的方法
var methods = type.GetMethods()
.Where(p=>p.IsDefined(typeof(ApiAttribute),true)).ToList();
foreach (var method in methods)
{
ApiAttribute? att = method.GetCustomAttribute(typeof(ApiAttribute)) as ApiAttribute;
Console.WriteLine($"方法名:{method.Name} 说明:{att?.name}");
//获取方法所有参数
var parameters = method.GetParameters();
foreach (var param in parameters)
{
Console.WriteLine($"参数名:{param.Name} 参数类型:{param.ParameterType.Name}");
}
//创建实例
var obj = Activator.CreateInstance(type);
var key = Console.ReadLine();
//调用方法
var res = method.Invoke(obj, new object[] { key });
//获取方法返回类型
var aa = method.ReturnType.Name;
Console.WriteLine($"调用方法返回类型:{aa} 返回结果:{res}");
}
}
下面来做个总结:
反射提供封装程序集、模块和类型的对象。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型。 然后,可以调用类型的方法或访问其字段和属性。 反射的典型用法如下所示:
使用?Assembly?来定义和加载程序集,加载程序集清单中列出的模块,以及在此程序集中定位一个类型并创建一个它的实例。
使用?Module?发现信息,如包含模块的程序集和模块中的类。 还可以获取所有全局方法或模块上定义的其它特定的非全局方法。
使用?ConstructorInfo?发现信息,如名称、参数、访问修饰符(如?public
?或?private
)和构造函数的实现详细信息(如?abstract
?或?virtual
)。 使用?Type?的?GetConstructors?或?GetConstructor?方法来调用特定构造函数。
使用?MethodInfo?发现信息,如名称、返回类型、参数、访问修饰符(如?public
?或?private
)和方法的实现详细信息(如?abstract
?或?virtual
)。 使用?Type?的?GetMethods?或?GetMethod?方法来调用特定方法。
使用?FieldInfo?发现信息,如名称、访问修饰符(如?public
?或?private
)和一个字段的实现详细信息 (如?static
);并获取或设置字段值。
使用?EventInfo?发现信息(如名称、事件处理程序的数据类型、自定义特性、声明类型以及事件的反射的类型),并添加或删除事件处理程序。
使用?PropertyInfo?发现信息(如名称、数据类型、声明类型,反射的类型和属性的只读或可写状态),并获取或设置属性值。
使用?ParameterInfo?发现信息,如参数的名称、数据类型、参数是输入参数还是输出参数以及参数在方法签名中的位置。
使用?CustomAttributeData?在于应用程序域的仅反射上下文中工作时发现有关自定义特性的信息。?CustomAttributeData?使你能够检查特性,而无需创建它们的实例。?System.Reflection.Emit?命名空间的类提供一种专用形式的反射,使你能够在运行时生成类型。
?