C# 反射实践

前言

大多数 程序 都要 处理 数据, 包括 读、 写、 操作 和 显示 数据。( 图形 也是 一种 数据 的 形式。) 然而, 对于 某些 程序 来说,它们 操作 的 数据 不是 数字、 文本 或 图形, 而是 程序 和 程序 类型 本身 的 信息。 有关 程序 及其 类型 的 数据 被称为 元 数据( metadata), 它们 保存 在 程序 的 程序 集中。 程序 在 运行时, 可以 查看 其他 程序 集 或 其 本身 的 元 数据。 一个 运行 的 程序 查看 本身 的 元 数据 或 其他 程序 的 元 数据 的 行为 叫做 反射( reflection)。

反射实践

一.制作程序集

打开vs新建一个类库

点下一步配置类库的路径和名字
在这里插入图片描述
创建好之后加入以下代码,代码中创建的一个Example类,加入一些字段、属性、和方法,并给他标记了自定义的特性MyAttribute,方便以后的测试

using System;

namespace MyDll
{
    //指定自定义特性只能附加到类上
    [AttributeUsage(AttributeTargets.Class)]
    public sealed class MyAttributeAttribute : System.Attribute
    {
        public string Description;
        public string Version;
        public string ReviewId;
        public MyAttributeAttribute(string desc, string ver)
        {
            Description = desc;
            Version = ver;
        }
    }
	
    [MyAttribute("MyClass", "1.0", ReviewId = "58946")]
    public class Example
    {
        public int a = 567;
        private int b = 555;
        public int B
        {
            get
            {
                return b;
            }
            set
            {
                b = value;
            }
        }
        public void HelloDll()
        {
            Console.WriteLine("HelloDll");
        }
        public void PrintOut(string s)
        {
            Console.WriteLine(s);
        }
    }
}

加入代码后 使用快捷键ctr + b 生成MyDll.dll文件,此时我们可以在项目中的MyDll\bin\Debug\netcoreapp3.1 文件夹下找到MyDll.dll文件,表示生成成功了

二.测试

新建C#控制台应用程序,运行测试代码如下

//加载程序集
Assembly assembly = Assembly.LoadFrom(@"D:\STu\csharp_-study\CSharp_Study\MyDll\bin\Debug\netcoreapp3.1\MyDll.dll");
Type type = assembly.GetType("MyDll.Example");
//创建类型实列
object obj = Activator.CreateInstance(type);
//调用方法
type.GetMethod("HelloDll").Invoke(obj,null);
//调用带参数的方法
type.GetMethod("PrintOut").Invoke(obj, new object[] { "DLLTEST" });
//获取属性
PropertyInfo propertyInfo = type.GetProperty("B");
//设置字段值
propertyInfo.SetValue(obj,444);
Console.WriteLine(propertyInfo.GetValue(obj, null));
//获取字段
FieldInfo fieldInfo = type.GetField("a");
//设置字段值
fieldInfo.SetValue(obj, 123);
Console.WriteLine(fieldInfo.GetValue(obj));

Console.WriteLine("================获取所有特性====================");
object[] typeAttributes = type.GetCustomAttributes(false);       //获取Example类的特性
foreach (object attribute in typeAttributes)
{
   Console.WriteLine("Attributes description is " + attribute.ToString());
   //获取特性Description信息
   Console.WriteLine($"Description:{attribute.GetType().GetField("Description").GetValue(attribute)}");
}

//获取所有成员
Console.WriteLine("================获取所有成员====================");
MemberInfo[] memberInfos = type.GetMembers();
foreach(var item in memberInfos)
{
   Console.WriteLine(item.Name);
}
//获取所有字段(默认公有,可以设置BindingFlags)
Console.WriteLine("================获取所有字段====================");
FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
foreach (var item in fieldInfos)
{
   Console.WriteLine(item.Name);
}
//获取所有属性
Console.WriteLine("================获取所有属性====================");
PropertyInfo[] properties = type.GetProperties();
foreach(var item in properties)
{
   Console.WriteLine(item.Name);
}

输出如下图
在这里插入图片描述

注意事项

关与Assembly.LoadFrom 方法可参见MSDN
关于Type类:

1)对于 程序 中 用到 的 每一个 类型, CLR 都会 创建 一个 包含 这个 类型 信息 的 Type 类型 的 对象。
2)程序 中 用到 的 每一个 类型 都会 关联 到 独立 的 Type 类 的 对象。
3)不管 创建 的 类型 有 多少 个 实例, 只有 一个 Type 对象 会 关联 到 所有这些 实例。

摘要

Daniel M·Solis. C#图解教程(第4版)(图灵图书) (p. 481). 人民邮电出版社. Kindle 版本.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值