C#中的反射

dll和exe文件的区别

  1. 用途

    • .exe(可执行文件):是可以直接运行的程序文件。当你双击一个 .exe 文件或在命令行中输入它的名字,操作系统会加载并执行这个程序。

    • .dll(动态链接库):包含可以被多个程序共享的代码和资源。.dll 文件不是直接运行的程序,而是作为其他程序的依赖项,提供函数、类、资源等。

  2. 执行

    • .exe 文件包含程序的入口点,操作系统通过这个入口点执行程序。

    • .dll 文件不包含入口点,它们是被 .exe 文件或其他 .dll 文件在运行时加载和使用的。

  3. 部署

    • .exe 文件通常作为独立的应用程序分发。

    • .dll 文件可以被多个应用程序共享,但有时也需要与使用它们的应用程序一起分发。

  4. 重用性

    • .exe 文件是自包含的,通常不设计为可重用的组件。

    • .dll 文件设计为可重用的组件,可以被不同的应用程序重复使用,以避免代码重复。

  5. 更新和维护

    • 更新 .exe 文件通常意味着替换整个应用程序文件。

    • 更新 .dll 文件可以只替换库文件,而不需要重新部署整个应用程序。

  6. 依赖性

    • .exe 文件可能依赖于特定的 .dll 文件来运行。

    • .dll 文件可能依赖于其他 .dll 文件(称为依赖项)。

  7. 编译

    • .exe 文件是程序的最终编译输出,包含了所有必要的代码和资源,准备直接运行。

    • .dll 文件是库项目的编译输出,通常不包含独立的程序逻辑。

  8. 系统整合

    • .exe 文件可以作为系统进程独立运行。

    • .dll 文件可以被整合到其他 .exe 文件中,作为它们功能的一部分。

反射的作用

操作metadata(元数据)的工具

反射的功能

反射提供了以下主要功能:

  1. 类型发现:可以查询类型的属性、方法、构造函数、事件、字段等。

  2. 类型创建:可以动态地创建类型的实例。

  3. 调用成员:可以调用类型的成员,如方法和属性。

  4. 修改访问修饰符:可以无视私有(private)、受保护(protected)等访问修饰符的限制,访问或修改成员的值。

  5. 泛型类型信息:可以获取泛型类型的参数信息。

  6. 自定义属性读取:可以读取类型或成员上定义的自定义属性。

调用反射的类名

复制代码
 static void Main(string[] args)
 {
     Assembly assembly1 = Assembly.Load("7.13day01");//加载方式一 dll文件名
     Assembly assembly2 = Assembly.LoadFile("D:\\C#daima\\7.13day\\bin\\Debug\\net8.0\\7.13day.dll");//加载方式二:完整路径名
     Assembly assembly3 = Assembly.LoadFrom("7.13day01.dll");
     Assembly assembly4 = Assembly.LoadFile("D:\\C#daima\\7.13day\\bin\\Debug\\net8.0\\7.13day.dll");
     foreach (var type in assembly1.GetTypes())
     {
         Console.WriteLine("assembly1类名" + type.Name);
         foreach (var field in type.GetMethods())
         {
             Console.WriteLine("assembly1方法名称:" + field);
         }
     }
​
     foreach (var type in assembly2.GetTypes())
     {
         Console.WriteLine("assembly2类名" + type.Name);
     }
     foreach (var type in assembly3.GetTypes())
     {
         Console.WriteLine("assembly3类名" + type.Name);
     }
     foreach (var type in assembly4.GetTypes())
     {
         Console.WriteLine("assembly4类名" + type.Name);
     }
 }
internal class Person
{
    public void Methed1()
    {
​
    }
    public void Methed2()
    {
​
    }
}

注意Load只能加载本文件下的dll

反射创建对象

复制代码
using System.Reflection;
​
namespace Mynamespase
{
    internal class ReflectionText
    {
​
​
        public void methed()
        {
            Console.WriteLine("方法");
        }
        static void Main(string[] args)
        {
            Assembly assembly = Assembly.LoadFrom("7.13day02.dll");//加载dll
            Type type = assembly.GetType("Mynamespase.ReflectionText");//获取类型
            object obj = Activator.CreateInstance(type);//创建对象
            ReflectionText refl = obj as ReflectionText;//类型转换as不报错,类型不对返回null 
            refl.methed();
        }
    }
}
​

as

在C#中,as 是一个关键字,用于执行引用类型的安全类型转换。as 运算符尝试将一个对象转换为指定的类型,如果转换失败,它不会抛出异常,而是返回 null。这使得 as 运算符成为在不确定能否成功转换类型时的一种安全选择。

as运算符的关键特性:

  1. 安全转换 :使用 as 运算符进行类型转换是安全的,因为如果转换不可能进行,结果将是 null,而不是抛出异常。

  2. 仅引用类型as 运算符只能用于引用类型或可空类型(nullable value types)。

  3. 隐式转换 :如果编译器确定转换是有效的,即存在从源类型到目标类型的隐式转换,那么 as 运算符可以成功转换而不会返回 null

  4. 失败时返回 null :如果转换不可能进行,as 运算符将返回 null,而不是 null 引用异常。

反射创建构造函数(带参数)

复制代码
using System.Reflection;
​
namespace Mynamespase
{
    internal class ReflectionText
    {
        int Age;
        public ReflectionText()
        {
            Console.WriteLine("这是无参构造");
        }
        public ReflectionText(int Age)
        {
            Console.WriteLine("这是有参构造");
        }
​
        public void methed()
        {
            Console.WriteLine("方法");
        }
        static void Main(string[] args)
        {
            Assembly assembly = Assembly.LoadFrom("7.13day02.dll");//加载dll
            Type type = assembly.GetType("Mynamespase.ReflectionText");//获取类型
            foreach (ConstructorInfo ctor in type.GetConstructors())//获取到所有的构造方法
            {
                Console.WriteLine(ctor.Name);
                foreach (ParameterInfo pi in ctor.GetParameters())
                {
                    Console.WriteLine(pi.ParameterType);
                }
            }
            Console.WriteLine("-------------------创建对象-----------------------");
            object obj1 = Activator.CreateInstance(type);//无参构造
            object obj2 = Activator.CreateInstance(type,new object[] { 123 });//无参构造
        }
    }
​
​
​
​
}
​

Activator.CreateInstance(type,true);后面加true可以创建私有的构造函数

设置类的属性

using System.Reflection;

namespace Mynamespase

{

internal class ReflectionText

{

public int Age;

public ReflectionText()

{

Console.WriteLine("这是无参构造");

}

public ReflectionText(int Age)

{

Console.WriteLine("这是有参构造");

}

public void methed()

{

Console.WriteLine("方法");

}

private static void Main(string[] args)

{

ReflectionText reflectionText = new ReflectionText();

reflectionText.Age = 12;

Type type = typeof(ReflectionText);

FieldInfo fieldInfo=type.GetField("Age",BindingFlags.Public | BindingFlags.Instance);

Console.WriteLine(fieldInfo.GetValue(reflectionText));

fieldInfo.SetValue(reflectionText, 22);

Console.WriteLine(fieldInfo.GetValue(reflectionText));

}

}

相关推荐
csdn_aspnet9 小时前
C# 算法 LeetCode 编号 70 - 爬楼梯
算法·leetcode·c#
魔法阵维护师9 小时前
从零开发游戏需要学习的c#模块,第二十五章(摄像机 —— 让世界比屏幕大)
学习·游戏·c#
周杰伦fans9 小时前
不支持目标框架: C#项目面向不再受支持的.NET Framework4.6.2
开发语言·c#·.net
richard_yuu10 小时前
C#零基础通关第六篇:吃透静态、常量与只读,分清静态与实例的本质差异
开发语言·c#
2501_9307077817 小时前
使用C#代码在 PowerPoint 中组合或取消组合形状
开发语言·c#
baivfhpwxf20231 天前
c# 中对像之间频繁的转换会慢吗?
开发语言·c#
加号31 天前
【C#】 实现 XRC 异或冗余校验:原理与实践
c#·xrc
小钻风33661 天前
Java + Spring Boot 操作 Kafka 完整学习指南
c#·linq
叫我少年1 天前
C# 程序的常规结构 — 命名空间、类型、入口点与表达式
c#