diff --git a/C#进阶/C#进阶.sln b/C#进阶/C#进阶.sln index f9ab673..18454a4 100644 --- a/C#进阶/C#进阶.sln +++ b/C#进阶/C#进阶.sln @@ -81,6 +81,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson19_预处理器指令 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson19_预处理器指令练习", "Lesson19_预处理器指令练习\Lesson19_预处理器指令练习.csproj", "{61DA81E2-A8D8-480E-B708-3D28334D76B0}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson20_反射", "Lesson20_反射概念和关键类Type\Lesson20_反射.csproj", "{1C0205AE-A49E-405D-A797-A0D2B6C37895}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "测试类库", "测试类库\测试类库.csproj", "{70C2E0D7-1F4A-4442-AF1C-3B1C2475B748}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lesson20_反射练习", "Lesson20_反射练习\Lesson20_反射练习.csproj", "{A93B1D1E-1A4D-47CB-AA26-2D08B3E557F1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "反射练习库", "反射练习库\反射练习库.csproj", "{86839643-1A23-454E-8B06-839900B3E032}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -243,6 +251,22 @@ Global {61DA81E2-A8D8-480E-B708-3D28334D76B0}.Debug|Any CPU.Build.0 = Debug|Any CPU {61DA81E2-A8D8-480E-B708-3D28334D76B0}.Release|Any CPU.ActiveCfg = Release|Any CPU {61DA81E2-A8D8-480E-B708-3D28334D76B0}.Release|Any CPU.Build.0 = Release|Any CPU + {1C0205AE-A49E-405D-A797-A0D2B6C37895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C0205AE-A49E-405D-A797-A0D2B6C37895}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1C0205AE-A49E-405D-A797-A0D2B6C37895}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1C0205AE-A49E-405D-A797-A0D2B6C37895}.Release|Any CPU.Build.0 = Release|Any CPU + {70C2E0D7-1F4A-4442-AF1C-3B1C2475B748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70C2E0D7-1F4A-4442-AF1C-3B1C2475B748}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70C2E0D7-1F4A-4442-AF1C-3B1C2475B748}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70C2E0D7-1F4A-4442-AF1C-3B1C2475B748}.Release|Any CPU.Build.0 = Release|Any CPU + {A93B1D1E-1A4D-47CB-AA26-2D08B3E557F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A93B1D1E-1A4D-47CB-AA26-2D08B3E557F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A93B1D1E-1A4D-47CB-AA26-2D08B3E557F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A93B1D1E-1A4D-47CB-AA26-2D08B3E557F1}.Release|Any CPU.Build.0 = Release|Any CPU + {86839643-1A23-454E-8B06-839900B3E032}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86839643-1A23-454E-8B06-839900B3E032}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86839643-1A23-454E-8B06-839900B3E032}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86839643-1A23-454E-8B06-839900B3E032}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/C#进阶/Lesson18_多线程练习/Program.cs b/C#进阶/Lesson18_多线程练习/Program.cs index 5b11fe1..b99a26e 100644 --- a/C#进阶/Lesson18_多线程练习/Program.cs +++ b/C#进阶/Lesson18_多线程练习/Program.cs @@ -26,6 +26,12 @@ Position.Y = 5; Direction = E_Direction.Right; } + public Snake(int x, int y,E_Direction direction) + { + Position.X = x; + Position.Y = y; + Direction = direction; + } public void Move() { diff --git a/C#进阶/Lesson20_反射概念和关键类Type/Lesson20_反射.csproj b/C#进阶/Lesson20_反射概念和关键类Type/Lesson20_反射.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/C#进阶/Lesson20_反射概念和关键类Type/Lesson20_反射.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/C#进阶/Lesson20_反射概念和关键类Type/Program.cs b/C#进阶/Lesson20_反射概念和关键类Type/Program.cs new file mode 100644 index 0000000..efb3330 --- /dev/null +++ b/C#进阶/Lesson20_反射概念和关键类Type/Program.cs @@ -0,0 +1,321 @@ +using System.Reflection; + +namespace Lesson20_反射 +{ + #region 知识回顾 + //编译器是一种翻译程序 + //它用于将源语言程序翻译为目标语言程序 + + //源语言程序:某种程序设计语言写成的,比如C#、Java、Python等 + //目标语言程序:计算机能够直接执行的机器语言程序(伪代码) + #endregion + + #region 知识点一 什么是程序集 + //程序集是我们写的一个代码集合,我们现在写的所有代码 + //最终都会背编译成一个程序集文件供别人使用 + //程序集文件的扩展名有两种:.exe和.dll + //.exe:可执行程序文件,双击即可运行 + //.dll:类库文件,不能直接运行,需要被其他程序调用才能运行 + #endregion + + #region 知识点二 元数据 + //元数据就是用来描述数据的数据 + //这个概念不仅仅用于程序上,在别的领域也有元数据 + + //说人话: + //程序中的类,类中的函数、变量等等信息就是 程序的 元数据 + //有关程序以及类型的数据被称为 元数据,他们保存在程序集文件中 + #endregion + + #region 知识点三 反射的概念 + //程序在运行时,可以查看其他程序集或者自身的元数据 + //一个运行的程序查看本身或者其他程序集的元数据的过程 就叫做 反射 + + //说人话: + //在程序运行时,通过反射可以得到其他程序集或者自己程序集代码的各种信息 + //类,函数,变量,对象等等,实例化他们,执行他们,操作他们 + #endregion + + #region 知识点四 反射的作用 + //因为反射可以在程序变异后获得信息,所以他提高了程序的拓展性和灵活性 + //1.程序运行时得到所有元数据,包括元数据的特性 + //2.程序运行时,实例化对象,操作对象 + //3.程序运行时创建新对象,用这些对象执执行任务 + #endregion + + + class Test + { + private int i = 1; + public int j = 2; + public string str = "123"; + + public Test() + { + + } + public Test(int i) + { + this.i = i; + + } + public Test(int i ,string str) + { + this.i = i; + this.str = str; + } + } + class Program + { + static void Main(string[] args) + { + + #region 知识点五 语法相关 + + #region Type类 + //Type(类的信息类) + //他是反射功能的基础! + //他是访问元数据的主要方式 + //使用Type的成员获取有关类型的声明信息 + //有关类型的成员(如构造函数、方法、属性、字段、事件等) + + #region 获取Type对象的方式 + //1.万物之父 Object类的GetType()方法 + int a = 42; + Type type = a.GetType();//得到int类型的类的信息 + Console.WriteLine(type);//获取int命名空间的全名 System.Int32 + //2.通过typeof关键字获取 + Type type2 = typeof(string);//得到string类型的类的信息 + Console.WriteLine(type2);//获取string命名空间的全名 System.String + //3.通过类的名字 也可以获取类型 + // 注意 类名必须包含命名空间 不然找不到 + Type type3 = Type.GetType("Int32");//非全名 + Console.WriteLine(type3);//获取不到 输出空行 + type3 = Type.GetType("System.Int32");//全名 + Console.WriteLine(type3);//获取int命名空间的全名 System.Int32 + Console.WriteLine("__________________________"); + #endregion + + #region 得到类的程序集信息 + //可以通过Type得到类型所在的程序集信息 + Console.WriteLine(type.Assembly); + Console.WriteLine(type2.Assembly); + Console.WriteLine(type3.Assembly); + Console.WriteLine("__________________________"); + #endregion + + #region 获取类中的所有公共成员 + //首先得到Type + Type t = typeof(Test); + //然后得到所有公共成员 + //需要引用命名空间 using System.Reflection; + MemberInfo[] infos = t.GetMembers(); + for (int i = 0; i < infos.Length; i++) + { + Console.WriteLine(infos[i]); + } + Console.WriteLine("__________________________"); + #endregion + + #region 获取类的公共构造函数并调用 + //1.获取所有构造函数 + ConstructorInfo[] ctors = t.GetConstructors(); + for (int i = 0; i < ctors.Length; i++) + { + Console.WriteLine(ctors[i]); + } + Console.WriteLine("__________________________"); + + + + //2.获取其中一个构造函数并执行 + //得到构造函数传入 Type数组 数组中内容按顺序时参数类型 + //执行构造函数传入 Object数组 表示按顺序传入的参数值 + + // 2-1得到无参构造并执行 + ConstructorInfo info = t.GetConstructor(new Type[0]);//由于使用时必须要传入参数类型数组 所以无参时传入空数组 + //执行无参构造方法 + //info.Invoke(null);//因为是无参构造函数,所以传入参数为null + //甚至可以实例化 + Test obj = info.Invoke(null) as Test; + Console.WriteLine(obj.j); + Console.WriteLine("__________________________"); + // 2-2得到无参构造并执行 + ConstructorInfo info2 = t.GetConstructor(new Type[] { typeof(int)}); + //执行有参构造方法 + Test obj2 = info2.Invoke(new object[] { 10 }) as Test; + //Console.WriteLine(obj2.i);//i是private类型所以外部无法访问 + //执行两个参数的构造函数 + ConstructorInfo info3 = t.GetConstructor(new Type[] { typeof(int), typeof(string) }); + Test obj3 = info3.Invoke(new object[] { 6 , "123" }) as Test; + Console.WriteLine(obj.str); + Console.WriteLine("__________________________"); + #endregion + + #region 获取类的公共成员变量 + //1.得到所有成员变量名和类型 + FieldInfo[] fieldInfos = t.GetFields(); + for (int i = 0; i < fieldInfos.Length; i++) + { + Console.WriteLine(fieldInfos[i]); + } + Console.WriteLine("__________________________"); + //2.得到指定成员变量名和类型 + FieldInfo infoJ = t.GetField("j"); + Console.WriteLine(infoJ); + Console.WriteLine("__________________________"); + //3.通过反射获取和设置成员变量的值 + Test test = new Test(); + test.j = 99; + test.str = "2222"; + //3-1获取成员变量j的值 + Console.WriteLine(infoJ.GetValue(test));//注意这里需要传入对象,因为都是写在一个文档里所以直接写上面new的test了 + //如果是其他程序集中则需要先通过反射实例化对象再传入 + //3-2设置成员变量j的值 + infoJ.SetValue(test, 100); + Console.WriteLine(infoJ.GetValue(test)); + Console.WriteLine("__________________________"); + #endregion + + #region 获取类的公共成员方法 + //通过Type类中的 GetMethods()方法可以获取类的所有公共方法 + //MethodInfo是方法的反射信息类 + Type strType = typeof(string); + //1.如果存在方法重载 用Type数组表示参数类型 + MethodInfo[] methods = strType.GetMethods(); + for (int i = 0; i < methods.Length; i++) + { + Console.WriteLine(methods[i]); + } + Console.WriteLine("__________________________"); + //2.调用该方法 + //注意:如果是静态方法 则传入null 如果是实例方法 则传入对象 + MethodInfo subStr = strType.GetMethod("Substring",new Type[] { typeof(int),typeof(int)}); + string str = "hello world!"; + object result = subStr.Invoke(str, new Object[] { 7, 5 }); + Console.WriteLine(result); + Console.WriteLine("__________________________"); + #endregion + + #region 其他 + //Type; + //得枚举 + //GetEnumName(); + //GetEnumNames(); + + //得事件 + //GetEvent(); + //GetEvents(); + + //得接口 + //GetInterface(); + //GetInterfaces(); + + //得属性 + //GetProperty(); + //GetPropertys(); + + //还有很多其他方法 可以查看文档学习 + #endregion + + #endregion + + #region Assembly类 + //程序集类 + //主要用来加载其他程序集,加载后 + //才能用Type来使用其他程序集中的信息 + //如果想要使用不是自己程序集中的内容 需要先加载程序集 + //比如dll文件(库文件) + //简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数、类等等 + + //三种加载程序集的函数 + //一般用来加载在同一文件下的其他程序集 + //Assembly asembly2= Assembly.Load("程序集名称"); + + //一般用来加载不在同一文件下的其它程序集 + //Assembly asembly = Assembly.LoadFrom("包含程序集清单的文件的名称或路径"); + //Assembly asembly3 = Assembly.LoadFile("要加载的文件的完全限定路径"); + + //1.先加载一个指定程序集 + Assembly asembly = Assembly.LoadFrom(@"D:\VisualStudio2022\VisualStudio Programe\C#\C#进阶\Lesson18_多线程练习\bin\Debug\net8.0\Lesson18_多线程练习.dll"); + + #region 如果不知道程序集载入的对不对可以用这个方法看一下 + Type[] types = asembly.GetTypes(); + foreach (Type item in types) + { + Console.WriteLine(item.FullName); + } + #endregion + + //2.再加载程序集中的一个类对象 之后才能使用反射 + Type snake = asembly.GetType("Lesson18_多线程练习.Snake"); + + #region 如果不知道有什么成员可以用这个方法看一下 + MemberInfo[] members = snake.GetMembers(); + for (int i = 0; i < members.Length; i++) + { + Console.WriteLine(members[i]); + } + #endregion + + //通过反射 实例化一个 Snake对象 + //先把枚举也传过来,来得到可传入的参数 + Type moveDir = asembly.GetType("Lesson18_多线程练习.E_Direction"); + FieldInfo right = moveDir.GetField("Right"); + //再实例化Snake对象 + Object snakeObj = Activator.CreateInstance(snake, 10 ,5 , right.GetValue(null)); + + //通过反射调用Snake对象的方法 + MethodInfo move = snake.GetMethod("Move"); + MethodInfo draw = snake.GetMethod("Draw"); + MethodInfo clean = snake.GetMethod("Clean"); + Console.Clear(); + while (true) + { + Thread.Sleep(400); + clean.Invoke(snakeObj, null); + move.Invoke(snakeObj, null); + draw.Invoke(snakeObj, null); + } + + //3.类库工程的创建 + //在Visual Studio中新建一个项目 选择 类库工程 + #endregion + + #region Activator类 + //用于快速实例化对象的类 + //用于将Type对象快速转换为实例对象 + //先得到Type 然后快速实例化对象 + Type testType = typeof(Test); + //1.无参构造 + Test testObj = Activator.CreateInstance(testType) as Test; + Console.WriteLine(testObj.str); + //2.有参构造 + Test testObj2 = Activator.CreateInstance(testType, 99) as Test;//一个参数的有参构造函数 + Console.WriteLine(testObj2.j); + Test testObj3 = Activator.CreateInstance(testType, 99, "111222") as Test;//两个个参数的有参构造函数 + Console.WriteLine(testObj3.str); + #endregion + + #endregion + } + } +} +//总结 +//反射 +//在程序运行时,通过反射可以得到其他程序集或者自己的程序集代码的各种信息 +//类、函数、变量、对象等等,实例化他们,执行他们,操作他们 + +//关键类 +//Type +//Assembly +//Activator + +//对于我们的意义 +//在初中级阶段 基本不会使用反射 +//所以目前对于大家来说,了解反射可以做什么就行 +//很长时间内都不会用到反射相关知识点 + +//为什么要学反射 +//为了之后学习Unity引擎的基本工作原理做铺垫 +//Unity引起的基本工作机制 就是建立在反射的基础上 \ No newline at end of file diff --git a/C#进阶/Lesson20_反射练习/Lesson20_反射练习.csproj b/C#进阶/Lesson20_反射练习/Lesson20_反射练习.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/C#进阶/Lesson20_反射练习/Lesson20_反射练习.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/C#进阶/Lesson20_反射练习/Program.cs b/C#进阶/Lesson20_反射练习/Program.cs new file mode 100644 index 0000000..eec5a53 --- /dev/null +++ b/C#进阶/Lesson20_反射练习/Program.cs @@ -0,0 +1,23 @@ +using System.Reflection; + +namespace Lesson20_反射练习 +{ + class Program + { + static void Main(string[] args) + { + Assembly assembly = Assembly.LoadFrom(@"D:\VisualStudio2022\VisualStudio Programe\C#\C#进阶\反射练习库\bin\Debug\反射练习库.dll"); + Type[] types = assembly.GetTypes(); + Console.WriteLine("______________"); + for (int i = 0; i < types.Length; i++) + { + Console.WriteLine(types[i]); + } + Console.WriteLine("______________"); + Type player = assembly.GetType("反射练习库.Player"); + + object obj = Activator.CreateInstance(player); + Console.WriteLine(obj); + } + } +} diff --git a/C#进阶/反射练习库/Properties/AssemblyInfo.cs b/C#进阶/反射练习库/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..a891486 --- /dev/null +++ b/C#进阶/反射练习库/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("反射练习库")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("反射练习库")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("86839643-1a23-454e-8b06-839900b3e032")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/C#进阶/反射练习库/test.cs b/C#进阶/反射练习库/test.cs new file mode 100644 index 0000000..6576ed9 --- /dev/null +++ b/C#进阶/反射练习库/test.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace 反射练习库 +{ + public struct Position + { + public int x; + public int y; + + public Position(int x,int y) + { + this.x = x; + this.y = y; + } + } + public class Player + { + public string name; + public int hp; + public int atk; + public int def; + public Position position; + public Player() + { + name = "英雄"; + hp = 100; + atk = 10; + def = 5; + position = new Position(0, 0); + } + } +} diff --git a/C#进阶/反射练习库/反射练习库.csproj b/C#进阶/反射练习库/反射练习库.csproj new file mode 100644 index 0000000..bcb5056 --- /dev/null +++ b/C#进阶/反射练习库/反射练习库.csproj @@ -0,0 +1,48 @@ + + + + + Debug + AnyCPU + {86839643-1A23-454E-8B06-839900B3E032} + Library + Properties + 反射练习库 + 反射练习库 + v4.7.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/C#进阶/测试类库/Class1.cs b/C#进阶/测试类库/Class1.cs new file mode 100644 index 0000000..05ce7a3 --- /dev/null +++ b/C#进阶/测试类库/Class1.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace 测试类库 +{ + //纯写代码类库,没有任何运行代码 + //没法点击运行,只能在项目中右键生成,这样就有dll文件了 + public class HK + { + } +} diff --git a/C#进阶/测试类库/Properties/AssemblyInfo.cs b/C#进阶/测试类库/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2b9356f --- /dev/null +++ b/C#进阶/测试类库/Properties/AssemblyInfo.cs @@ -0,0 +1,33 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("测试类库")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("测试类库")] +[assembly: AssemblyCopyright("Copyright © 2025")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("70c2e0d7-1f4a-4442-af1c-3b1c2475b748")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/C#进阶/测试类库/测试类库.csproj b/C#进阶/测试类库/测试类库.csproj new file mode 100644 index 0000000..ba77138 --- /dev/null +++ b/C#进阶/测试类库/测试类库.csproj @@ -0,0 +1,54 @@ + + + + + Debug + AnyCPU + 70c2e0d7-1f4a-4442-af1c-3b1c2475b748 + Library + Properties + 测试类库 + 测试类库 + v4.7.2 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + +