C# - 利用反射将 string 类名动态转化成类 并访问其字段和方法

引言

最近有在 .NET 平台搭建 API Automation Framework, 就有遇到怎么将字符串类名转换成类,并访问其常量属性,很久没有弄 .NET 的东西,很是生疏。所以特意研究了一下,利用 Reflection 反射就可以解决这个问题。

内容提要:

  1. 反射 Reflection 的几个主要方法
  2. 完整代码举例

反射 Reflection 的几个主要方法

介绍一下几个要点:

  1. 引用 Reflection
using System.Reflection;
  1. 字符串转换成类
    注意要加上 namespace
Type type = Type.GetType(namespaceStr + "." + className);
  1. 访问字段,返回字段数组
    默认是访问所有 public 的字段,包括父类继承的字段
FieldInfo[] default_fields = type.GetFields();

当然也可以加上条件过滤一下,下面是访问所有 private, public 的字段。

FieldInfo[] all_fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);

有在 BindingFlags 选项可以参考源代码中的注释:
在这里插入图片描述

  1. 访问单个字段值
    注意这种方式只能访问类字段,访问实例变量是会抛异常的
type.GetField("Const_Field_Name").GetValue(type)

注意上述方法不能访问父类的常量字段,可以通过 BaseType 得到父类 Type

type.BaseType.GetField("Parent_Const_field_name").GetValue(type)
  1. 方法调用
MethodInfo method = type.GetMethod("Method_Name");
method.Invoke(instance_object, object[] parameters);
  1. 实例化类对象
object instance_object = Activator.CreateInstance(type);

完整代码举例

将上面介绍的点串起来应用一下, 定义了一对父子类,分别有不同的字段和方法,通过反射 Reflection 来访问其不同字段和方法,通过程序运行结果,可以更好的理解代码。

using System.Reflection;

namespace ConsoleApp1
{
    public class ParentClass
    {
        public const string P_CONST_STR = "Parent Const str";
        private string p_private_str = "Private str";
        public string p_public_Str = "Public str";
        public void P_Method_call(string p1,string p2)
        {
            Console.WriteLine("P Method_call" + " with parameter " + p1 + " and " + p2);
        }
    }

    public class childClass : ParentClass
    {
        public const string C_CONST_STR = "Child Const str";
        private string c_private_str = "Private str";
        public string c_public_Str = "Public str";

        public void C_Method_call()
        {
            Console.WriteLine("C Method_call");
        }
    }

    public class Test
    {
        static void Main(string[] args)
        {
            string namespaceStr = "ConsoleApp1";
            string className = "childClass";

            Type child_type = Type.GetType(namespaceStr + "." + className);
            FieldInfo[] all_fields = child_type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
            FieldInfo[] default_fields = child_type.GetFields();

            Console.WriteLine("====All Fields:====");
            foreach (FieldInfo field in all_fields)
            {
                Console.WriteLine(field.Name);
            }
            Console.WriteLine("====Default Fields Without Filters:====");
            foreach (FieldInfo field in default_fields)
            {
                Console.WriteLine(field.Name);
            }
            Console.WriteLine("====Acess Const Field Value:====");
            Console.WriteLine("Acess const field value: " + child_type.GetField("C_CONST_STR").GetValue(child_type));
            Console.WriteLine("Acess const field value: " + child_type.BaseType.GetField("P_CONST_STR").GetValue(child_type));

            Console.WriteLine("====Call Methods:====");
            MethodInfo c_method = child_type.GetMethod("C_Method_call");
            MethodInfo p_method = child_type.GetMethod("P_Method_call");
            object instance_child = Activator.CreateInstance(child_type);
            c_method.Invoke(instance_child, null);
            object[] parameterObject = new object[] {"p1_value", "p2_value"};
            p_method.Invoke(instance_child, parameterObject);
        }
    }
}

输出:

====All Fields:====
c_private_str
c_public_Str
C_CONST_STR
p_public_Str
====Default Fields Without Filters:====
c_public_Str
C_CONST_STR
p_public_Str
====Acess Const Field Value:====
Acess const field value: Child Const str
Acess const field value: Parent Const str
====Call Methods:====
C Method_call
P Method_call with parameter p1_value and p2_value
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值