dll和exe文件的区别
-
用途:
-
.exe
(可执行文件):是可以直接运行的程序文件。当你双击一个.exe
文件或在命令行中输入它的名字,操作系统会加载并执行这个程序。 -
.dll
(动态链接库):包含可以被多个程序共享的代码和资源。.dll
文件不是直接运行的程序,而是作为其他程序的依赖项,提供函数、类、资源等。
-
-
执行:
-
.exe 文件包含程序的入口点,操作系统通过这个入口点执行程序。
-
.dll 文件不包含入口点,它们是被
.exe
文件或其他 .dll 文件在运行时加载和使用的。
-
-
部署:
-
.exe
文件通常作为独立的应用程序分发。 -
.dll
文件可以被多个应用程序共享,但有时也需要与使用它们的应用程序一起分发。
-
-
重用性:
-
.exe
文件是自包含的,通常不设计为可重用的组件。 -
.dll
文件设计为可重用的组件,可以被不同的应用程序重复使用,以避免代码重复。
-
-
更新和维护:
-
更新
.exe
文件通常意味着替换整个应用程序文件。 -
更新
.dll
文件可以只替换库文件,而不需要重新部署整个应用程序。
-
-
依赖性:
-
.exe
文件可能依赖于特定的.dll
文件来运行。 -
.dll
文件可能依赖于其他.dll
文件(称为依赖项)。
-
-
编译:
-
.exe
文件是程序的最终编译输出,包含了所有必要的代码和资源,准备直接运行。 -
.dll
文件是库项目的编译输出,通常不包含独立的程序逻辑。
-
-
系统整合:
-
.exe
文件可以作为系统进程独立运行。 -
.dll
文件可以被整合到其他.exe
文件中,作为它们功能的一部分。
-
反射的作用
操作metadata(元数据)的工具
反射的功能
反射提供了以下主要功能:
-
类型发现:可以查询类型的属性、方法、构造函数、事件、字段等。
-
类型创建:可以动态地创建类型的实例。
-
调用成员:可以调用类型的成员,如方法和属性。
-
修改访问修饰符:可以无视私有(private)、受保护(protected)等访问修饰符的限制,访问或修改成员的值。
-
泛型类型信息:可以获取泛型类型的参数信息。
-
自定义属性读取:可以读取类型或成员上定义的自定义属性。
调用反射的类名
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运算符的关键特性:
-
安全转换:使用
as
运算符进行类型转换是安全的,因为如果转换不可能进行,结果将是null
,而不是抛出异常。 -
仅引用类型:
as
运算符只能用于引用类型或可空类型(nullable value types)。 -
隐式转换:如果编译器确定转换是有效的,即存在从源类型到目标类型的隐式转换,那么
as
运算符可以成功转换而不会返回null
。 -
失败时返回 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));
}
}