Reflection —— 反射
一时反射一时爽,一直反射一直爽
获取属性信息
Type compareInfoType = typeof(CompareItem);
PropertyInfo[] properties = compareInfoType.GetProperties();
随后可通过properties[i].Name获取属性名,properties[i].GetValue(obj)获取属性值(其中obj)是具体的实例
创建对象
通过反射创建对象,需要获取构造函数信息,并调用构造函数的Invoke方法,传入参数,即可创建对象
下面这个例子中,CreateInstance方法要通过dataRow中的数据,使用反射创建T类型的对象
public static T CreateInstance<T>(DataRow dataRow)
{
Type type = typeof(T);
ConstructorInfo constructorInfo = type.GetConstructor(new Type[] { });
if(constructorInfo != null)
{
//调用类的无参构造函数创建对象
T instance = (T)constructorInfo.Invoke(new object[] { });
PropertyInfo[] properties = type.GetProperties();
foreach(PropertyInfo property in properties)
{
if (dataRow.Table.Columns.Contains(property.Name)
&& dataRow.Table.Columns[property.Name].DataType == property.PropertyType)
{
property.SetValue(instance, dataRow[property.Name]);
}
}
return instance;
}
return default(T);
}
如果是有参构造函数,则将type.GetConstructor(new Type[] { })中的参数类型换成构造函数的参数类型即可 如:
public class ExampleClass
{
public int Id { get; set; }
public string Name { get; set; }
// 有参构造函数
public ExampleClass(int id, string name)
{
Id = id;
Name = name;
}
}
可通过以下代码获取有参构造函数信息
如果想要调用有参但有默认值的构造方法时,可以使用Type.Missing在Invoke时占位
public class MyClass
{
// 带有默认参数的构造方法
public MyClass(int requiredParam, string optionalParam = "default", bool flag = true)
{
Console.WriteLine($"构造方法被调用: requiredParam={requiredParam}, optionalParam={optionalParam}, flag={flag}");
}
}
public class Program
{
public static void Main()
{
// 获取类型信息
Type type = typeof(MyClass);
// 定义参数类型数组(包含默认参数)
Type[] paramTypes = new Type[] { typeof(int), typeof(string), typeof(bool) };
// 获取构造函数信息
ConstructorInfo constructor = type.GetConstructor(
BindingFlags.Public | BindingFlags.Instance,
binder: null,
types: paramTypes,
modifiers: null
);
if (constructor != null)
{
// 调用构造函数,使用 Type.Missing 表示使用默认值+++++++
object instance = constructor.Invoke(new object[] { 42, Type.Missing, Type.Missing });
Console.WriteLine("对象创建成功!");
}
else
{
Console.WriteLine("未找到匹配的构造函数!");
}
}
反射访问私有字段
虽然说私有变量不能直接访问,但是通过反射,可以访问私有属性
//示例类
public class MyClass
{
public int PublicField;
private int PrivateField;
public static int PublicStaticField;
private static int PrivateStaticField;
}
BindingFlags.NonPublic,如果不指定BindingFlags.Instance的话,只会检索私有的静态字段 如: //效果和上面一样
FieldInfo[] nonPublicFields = myType.GetFields(BindingFlags.NonPublic| BindingFlags.Static);
结果:
如果要同时获取实例字段,则要指定BindingFlags.Instance
FieldInfo[] nonPublicFields = myType.GetFields(BindingFlags.NonPublic| BindingFlags.Static|BindingFlags.Instance);
而如果不指定搜索条件的话,则会同时检索到公有的实例和静态字段,私有的不会被检索出来