c#的特性和反射(二)

反射和特性(详细)

反射

C# 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace _03_反射
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // System.Reflection 命名空间中的类与 System.Type 使你能够获取有关加载的程序集和其中定义的类型的信息,如类、接口和值类型(即结构和枚举)。
            // 可以使用反射在运行时创建、调用和访问类型实例。

            // 反射就是提供了一种可以动态访问程序集成员的一种方案

            // ----------------反射可以让我们动态的添加程序
            // 使用反射动态的加载程序
            Assembly assembly = Assembly.LoadFile(@"C:\Users\g8496\Desktop\11-6\01 作业\bin\Debug\01 作业.exe");
            Type[] types = assembly.GetTypes();
            foreach (Type type in types)
            {
                Console.WriteLine(type.FullName);
            }

            // ---------------反射可以根据类型读取该类型中的信息
            // System.Type  一般上作为我们使用反射的入口,大部分反射的操作都要使用 System.Type来完成
            // Type 是一个类,存储某个类型的详细信息,也就是元数据(metadata),可以用它获取到该类的属性和方法
            Type t1 = typeof(string);   // 使用 typeof(类型) 获取该类型的详细信息
            Type t2 = typeof(int);
            Type t3 = typeof(Dog);

            Dog dog = new Dog();    // 根据现有对象获取类型的详细信息
            Type t4 = dog.GetType();


            // ------------------使用Type获取某个类的所有属性
            // 1、根据对应的类型生成Type对象
            Type d = typeof(Dog);
            // 2、调用方法获取属性
            PropertyInfo[] infos = d.GetProperties();
            // 3、循环所有的属性
            foreach (PropertyInfo info in infos)
            {
                Console.WriteLine(info.Name);   // 属性的名字
            }


            Console.ReadLine();
        }
    }
}

动态加载DLL

C# 复制代码
using ClassLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace _04_动态加载DLL
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 我们可以使用反射来动态的读取dll文件中的元数据,包括这个dll中有哪些类、属性、方法


            // Load     只写dll的文件名,但是要保证当前项目的运行目录中有该dll文件    
            // Assembly as1 =  Assembly.Load("ClassLibrary");

            // LoadFile 加载指定路径下的dll文件,需要写绝对路径(从盘符(C: D:)开始的路径)
            // Assembly as2 = Assembly.LoadFile(@"C:\Users\g8496\Desktop\11-6\04 动态加载DLL\bin\Debug\ClassLibrary.dll");

            // LoadFrom 加载指定路径下的dll文件,支持绝对路径和相对路径(注意:要带文件后缀)
            Assembly as3 =  Assembly.LoadFrom(@"ClassLibrary.dll");


            // Assembly 加载了对应的dll后,其中存储了该程序中所有的类型

            // GetTypes()   获取该dll/exe中所有的类型
            Type[] ts = as3.GetTypes();
            foreach (Type v in ts)
            {
                // Type.FullName    获取该类型的完全限定名(带有命名空间的类名)
                // Type.Name        获取该类型的名字(类名)
                Console.WriteLine($"v.FullName: {v.FullName}    Name:{v.Name}");
            }


            // Type至关重要,它是对程序元数据访问和操作的入口
            Type t = typeof(People);    // 根据类获取类型
            Console.WriteLine(t.FullName); 

            Type t1 = new People().GetType();   // 根据对象获取类型
            Console.WriteLine(t1.FullName);


            // 封装方法输出完全限定名
            WriteFullName<string>();
            WriteFullName<Dog>();
            Console.ReadLine();
        }

        // 输出类的完全限定名
        static void WriteFullName<T>()
        {
            Type t = typeof(T);
            Console.WriteLine(t.FullName);
        }
    }
}

反射操作

C# 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ClassLibrary;

namespace _05_反射操作
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Assembly assembly = Assembly.LoadFrom("ClassLibrary.dll");

            // GetTypes 获取dll中所有的类型
            Type[] types = assembly.GetTypes();
            // GetType  获取程序中指定的类型,参数为对应类型的完全限定名(带命名空间的)
            Type t = assembly.GetType("ClassLibrary.User");

            // 使用 Type.GetProperties    获取该类型的所有属性
            PropertyInfo[] infos = t.GetProperties();
            foreach (PropertyInfo info in infos)
            {
                Console.WriteLine("属性:" + info.Name + "类型:" + info.PropertyType);
            }
            // 使用   Type.GetMethods   获取该类型的所有方法
            // 包含属性的get、set,以及类自己的方法,还有继承自父类的方法
            MethodInfo[] methods =  t.GetMethods();
            foreach (MethodInfo method in methods)
            {
                Console.WriteLine("方法" + method.Name);
            }

            Console.WriteLine("----------------------------------");

            // 使用反射实例化类
            {
                // 根据某个类型信息生成实例(new操作),执行无参构造
                object o = Activator.CreateInstance(t);
            }
            {
                // 执行有参构造方法创建对象
                object o1 = Activator.CreateInstance(t, new object[] { "1","张三","155555",11});
                object o2 = Activator.CreateInstance(t, new object[] { "张三", 18 });
            }
            {
                // 获取类型的所有构造方法(了解)
                ConstructorInfo[] ctors = t.GetConstructors();  // 获取所有构造方法
                foreach (ConstructorInfo ctor in ctors) 
                {
                    Console.WriteLine(ctor.Name);   // 构造方法的名字都是  .ctor
                    ParameterInfo[] parameters = ctor.GetParameters();  // 获取当前构造方法的参数列表
                    Console.WriteLine(parameters.Length); // 当前构造方法的参数个数
                    Console.Write("所需参数:");
                    foreach (ParameterInfo v in parameters) // 循环参数列表
                    {
                        // v.Name   参数名
                        // v.ParameterType  参数类型
                        Console.WriteLine(v.Name + ":" + v.ParameterType);
                    }
                    Console.WriteLine();
                }
            }
            Console.WriteLine("------------------------");
            {
                // 使用反射,即使该类的访问修饰符为:internal,照样可以通过反射访问它并实例化

                // new Dog();       报错,因此Dog的修饰符为internal
                Type d = assembly.GetType("ClassLibrary.Dog");
                object o = Activator.CreateInstance(d);


                // new ClassLibrary.Cai.Qiu.Kun();      报错,因为构造方法是私有的
                Type d1 = assembly.GetType("ClassLibrary.Cai.Qiu.Kun");
                object o1 = Activator.CreateInstance(d1, true); // 参数2给一个true,表示该构造方法可能为非公开(非 public)的
            }




            Console.ReadLine();
        }
    }
}

使用反射创建泛型类

C# 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ClassLibrary;

namespace _06_使用反射创建泛型类
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //new TestTClass<int, string, bool>(1, "测试", true);
            //new TestTClass<int, double, char>(1, 2.2, 'c');

            // 如何使用反射创建泛型类
            // 1、加载程序
            Assembly assembly = Assembly.LoadFrom("ClassLibrary.dll");
            // 2、获取对应的类型(注意:如果该类型拥有泛型参数,需要以 `数字   结尾,数字取决于泛型的个数)
            Type t = assembly.GetType("ClassLibrary.TestTClass`3");
            // 3、带有泛型参数的类型其实是一个不完整的类型,因此带有泛型参数的类型不能直接使用,需要指定对应的泛型参数
            // 根据泛型类型生成新的类型
            // 注意:传入的应该是一个 Type 类型,使用 typeof 生成
            Type newT = t.MakeGenericType(typeof(int), typeof(string), typeof(bool));

            // newT  == TestTClass<int, string, bool>

            // 4、进行实例化
            object o = Activator.CreateInstance(newT, new object[] {123,"张三",false});

            Console.ReadLine();
        }
    }
}

使用反射调用方法

C# 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TestLibrary;

namespace _02_使用反射调用方法
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 1、加载程序
            Assembly assembly = Assembly.LoadFrom("TestLibrary.dll");
            // 2、获取对应的类型
            Type peopleType = assembly.GetType("TestLibrary.People");
            // 3、创建实例化对象
            object o1 = Activator.CreateInstance(peopleType, new object[] { "张三", 20 });
            object o2 = Activator.CreateInstance(peopleType, new object[] { "李四", 21 });

            Console.WriteLine("----------------调用无参的方法---------------");
            {
                // 不适用委托调用方法:
                // People p1 = new People();
                // p1.Say();

                // 使用反射调用方法
                // 1、获取该类型中对应名字的方法
                MethodInfo method = peopleType.GetMethod("Eat");
                // 2、调用方法,
                // 参数1:指定该方法在哪个实例上运行
                // 参数2:调用方法传递的参数,如果没有参数可以传null
                method.Invoke(o1, null);    // 我张三会吃饭

                method.Invoke(o2, null);    // 我李四会吃饭
            }
            Console.WriteLine("---------------调用有参构造-------------------");
            {
                MethodInfo method = peopleType.GetMethod("Play");
                method.Invoke(o1, new object[] { "穿越火线" });
                method.Invoke(o1, new object[] { "元神启动" });
                method.Invoke(o2, new object[] { "PUBG" });
            }
            Console.WriteLine("---------------调用重载方法-------------------");
            {
                // 如果一个方法拥有多个重载,那么在获取该方法时就必须手动指定方法的类型
                MethodInfo method = peopleType.GetMethod("Say", new Type[] { });
                method.Invoke(o1, null);

                MethodInfo method1 = peopleType.GetMethod("Say", new Type[] { typeof(string) });
                method1.Invoke(o1, new object[] { "小红叫我去网吧,我置之不理" });

                MethodInfo method2 = peopleType.GetMethod("Say", new Type[] { typeof(string), typeof(string) });
                method2.Invoke(o1, new object[] { "今天上网吧打通宵", "小明"   });
            }
            Console.WriteLine("---------------调用私有方法-------------------");
            {
                // 调用私有方法
                MethodInfo method = peopleType.GetMethod("Test", BindingFlags.Instance | BindingFlags.NonPublic);
                method.Invoke(o2, null);

                // 调用私有的重载方法
                // Type.GetMethod(方法名, BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[]{ 参数类型 }, null)
                MethodInfo method1 = peopleType.GetMethod("Test1", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(string) }, null);
                method1.Invoke(o2, new object[] {"测试"});

                MethodInfo method2 = peopleType.GetMethod("Test1", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(string), typeof(int) }, null);
                method2.Invoke(o2, new object[] { "测试222", 999 });
            }

            // 重要:GetMethod     Invoke

            Console.ReadLine();
        }
    }
}

属性操作

C# 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using TestLibrary;

namespace _03_属性操作
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 1、加载程序
            Assembly assembly = Assembly.LoadFrom("TestLibrary.dll");
            // 2、获取类型
            Type peopleType = assembly.GetType("TestLibrary.People");
            
            
            // 创建实例
            object o = Activator.CreateInstance(peopleType);

            // 1、获取类型中所有的属性
            PropertyInfo[] infos = peopleType.GetProperties();
            foreach (PropertyInfo pi in infos)
            {
                Console.WriteLine($"属性名:{pi.Name} 类型:{pi.PropertyType}");
            }


            {
                // 2、使用反射设置对象的属性
                // 2-1、先获取对应的属性
                PropertyInfo nameInfo = peopleType.GetProperty("Name");
                // 2-2、设置对应对象的属性值
                // 参数1:设置到哪个对象上
                // 参数2:设置的属性值
                nameInfo.SetValue(o, "张三");

                // 设置对象o的Age属性为22
                PropertyInfo a = peopleType.GetProperty("Age");
                a.SetValue(o, 22);
            }

            {
                // 3、使用反射读取对象的属性
                // 3-1、获取对应的属性
                PropertyInfo nameInfo = peopleType.GetProperty("Name");
                // 3-2、读取对应对象的属性值
                Console.WriteLine("o对象的Name属性值为:" + nameInfo.GetValue(o));
            }


            Console.WriteLine("============");
            // 在控制台输出该参数的所有属性名、属性值、属性类型
            People p1 = new People();
            Test.Fn(p1);
            Test.Fn(new People() { Name = "万物", Age = 30 });



            Console.ReadLine();
        }
    }

    class Test
    {
        public static void Fn<T>(T v)
        {
            // 1、获取该类型的Type
            Type t = typeof(T);
            // Type t = v.GetType(); // 或者

            // 2、获取该Type的所有属性
            PropertyInfo[] properties = t.GetProperties();

            // 3、循环所有属性
            foreach (PropertyInfo pi in properties) {
                // 输出属性名,属性类型,属性值
                Console.WriteLine($"{pi.Name}: {pi.PropertyType} = {pi.GetValue(v)}");
            }
        }
    }
}

特性

C# 复制代码
// #define abc     // 定义一个预处理标识   abc
// 一般预处理标识仅在当前文件中生效,如果需要该标识在整个项目中生效,需要在项目的Properties

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _05_特性
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 什么是特性
            // **特性(Attribute)**是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。您可以通过使用特性向程序添加声明性信息。一个声明性标签是通过放置在它所应用的元素前面的方括号([ ])来描述的。
            // 特性(Attribute)用于添加元数据,如编译器指令和注释、描述、方法、类等其他信息。

            // .Net 框架提供了两种类型的特性:预定义特性(内置特性)和自定义特性。

            // 特性的语法如下
            // 特性(Attribute)的名称和值是在方括号内规定的,放置在它所应用的元素之前。positional_parameters 规定必需的信息,name_parameter 规定可选的信息。

            // [attribute(必须的信息1, 必须的信息2, 可选的信息 = value, 可选的信息 = value)]
            // 元素

            // 特性就是给C#中的元素(类、属性、字段、方法...)添加一些其他的信息

            // 预定义特性(内置特性)
            Test test = new Test();
            test.Fn();
            test.Fn1();
            test.Fn2();
            test.Fn3();

            for (int i = 0; i < 100; i++)
            {
                test.TestMethodSpeed();
            }
            new Class1().Fn();

            Console.WriteLine("Obsolete特性");
            test.Fn4();
            test.Fn5();
            // test.Fn7();

            Console.ReadLine();
        }
    }

    class Test
    {
        // Conditional(名字)      该特性标记了一个条件,如果执行编译时定义了该预处理标识符,这个属性或者方法才会被定义和调用
        [Conditional("abc")]
        public void Fn()
        {
            Console.WriteLine("我是Fn方法,abc标识被定义时执行");
        }
        [Conditional("abc")]
        public void Fn1()
        {
            Console.WriteLine("我是Fn1方法,abc标识被定义时执行");
        }
        [Conditional("DEBUG")]
        public void Fn2()
        {
            Console.WriteLine("我是Fn2,DEBUG标识被定义时执行");
        }
        [Conditional("aaa")]
        public void Fn3()
        {
            Console.WriteLine("我是Fn3,aaa标识被定义时执行");
        }


        // 测试方法的速度
        [Conditional("DEBUG")]
        public void TestMethodSpeed()
        {
            Console.WriteLine("假装测试方法的执行速度,DEBUG标识被定义时执行");
        }

        [Obsolete("这个方法不让用了")]
        public void Fn4() { }
        [Obsolete("Fn5已经过时,请你使用Fn6方法")]
        public void Fn5() { }
        public void Fn6() { }

        // 参数2传递一个布尔值,表示如果使用该方法是是否展示一个错误而不是警告
        [Obsolete("提示信息", true)]
        public void Fn7() { }


        // 同时使用多个特性
        [Conditional("DEBUG")]
        [Obsolete("过时了")]
        public void Fn8()
        {

        }

        // 同时使用多个特性的另一种写法
        [Conditional("DEBUG"), Obsolete("过时了")]
        public void Fn9()
        {

        }
    }
}

自定义特性

C# 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _06_自定义特性
{
    // 自定义特性就是一个类,需要继承子Attribute
    // 一般我们自定义的特性都以Attribute结尾,在使用该特性时可以省略Attribute

    // 创建了一个特性,该特性用于记录某个元素的bug修复情况
    public class BugFixAttribute : Attribute
    {
        // bug修复者
        public string Name { get; set; }
        // bug修复时间
        public string Time { get; set; }
        // bug的描述信息
        public string Description { get; set; }
        public BugFixAttribute(string name, string time)
        {
            Name = name;
            Time = time;
        }
    }
    public class LaoguoAttribute: Attribute {
        public int  A { get; set; }
        public string B { get; set; }
        public LaoguoAttribute(int a)
        {
            A = a;
        }
    }
    // 有一个内置的特性用于规定我们的特性可以用在什么地方
    // 默认特性可以用在所有的地方
    // Method   方法
    // Property 属性
    // Constructor  构造函数
    // Field    字段
    // Class    类
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Constructor | AttributeTargets.Field | AttributeTargets.Class )]
    public class ABCAttribute : Attribute
    {

    }
}
//------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _06_自定义特性
{
    internal class Program
    {
        static void Main(string[] args)
        {
        }
    }

    // [ABCAttribute]
    [ABC]       // 简化
    // 构造方法中要求的参数直接写,非构造方法要求的参数  xxxx = xxxx  的格式书写
    [BugFix("老王", "2023-10-21", Description = "修复了一个不执行的bug")]
    class Test
    {
        // 19行这种写法类似于类实例化时
        // new BugFixAttribute("老王", "2023-10-21")
        // {
        //     Description = "修复了一个不执行的bug"
        // }
    }
    [BugFix("老李", "2023-11-23")]
    [Laoguo(1, B = "B的值")]
    class People
    {

    }





    [ABC]
    class A
    {
        [ABC]
        private int x;
        [ABC]
        public int MyProperty { get; set; }
        [ABC]
        public void Fn() { }
        [ABC]
        public A()
        {
            
        }
    }
}

特性的应用

C# 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace _02_特性
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Type t = typeof(Peolpe);

            // 反射的作用就是用来读取类型上的一些元数据
            Console.WriteLine(t.Name);  // 类名
            Console.WriteLine(t.FullName);  // 完全限定名
            Console.WriteLine(t.Namespace); // 命名空间


            // 特性就是给C#的元素添加了一些其他的信息(元数据)
            // GetCustomAttributes      获取元素上所有的特性
            // 参数:如果只传递一个Bool值,表示是否要获取该类继承自别的类的特性
            var b1 = typeof(A).GetCustomAttributes(true);   // 1个特性
            var b2 = typeof(A).GetCustomAttributes(false);  // 0个特性
            // 另一个重载,用于筛选我们要获取该元素上的哪些特性
            // 参数1:你要获取哪个类型的特性
            // 参数2:传递一个Bool值,表示是否要获取该类继承自别的类的特性
            var b3 = t.GetCustomAttributes(typeof(EfgAttribute), false);
            var b4 = t.GetCustomAttributes(typeof(BugFixAttribute), false);


            // 获取某一个特性
            Attribute attribute = t.GetCustomAttribute(typeof(BugFixAttribute));
            Console.WriteLine("t这个类型拥有特性BigFix,修改该bug的人是:" + (attribute as BugFixAttribute).Name);


            // 练习:获取People类型上的属性bug修复情况
            // 1、先获取所有的属性
            foreach (PropertyInfo p in t.GetProperties())
            {
                // 2、获取该属性的 BugFixAttribute 特性
                Attribute att = p.GetCustomAttribute(typeof(BugFixAttribute));
                // 3、如果有该特性,则输出即可
                if(att != null)
                {
                    Console.WriteLine($"{p.Name}属性被修复,修改人:{(att as BugFixAttribute).Name}");
                }
            }


            Console.ReadKey();
        }
    }

    // 使用该特性
    [BugFix("张三")]
    [Efg]
    [Efg]
    [Efg]
    class Peolpe
    {
        [BugFix("王五")]
        public int MyProperty1 { get; set; }
        [BugFix("王五")]
        public int MyProperty2 { get; set; }
        public int MyProperty3 { get; set; }
    }

    // 创建了一个自定义特性
    class BugFixAttribute : Attribute
    {
        public string Name { get; set; }
        public BugFixAttribute(string name)
        {
            Name = name;
        }
    }

    // Inherited    如果为true,则使用了该特性的类的子类也会继承该特性(如下例中 A 类同样会拥有 B 类的特性)
    [AttributeUsage(AttributeTargets.All, Inherited = true)]
    class AbcAttribute : Attribute { }

    [AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
    class EfgAttribute : AbcAttribute { }

    [Abc]
    class B { }
    class A : B { }

}
//===================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace _03_特性使用练习
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Test.BugLog<People>();


            Console.ReadLine();
        }
    }
    [BugFix("张三", "2023-10-22", "测试一下")]
    class People
    {
        [BugFix("张三", "2023-10-22", "测试一下")]
        public int MyProperty { get; set; }
        public int MyProperty1 { get; set; }
        [BugFix("张三", "2023-10-22", "测试一下")]
        public void Fn()
        {

        }
        public void Fn1()
        {

        }
    }
    class Test
    {
        public static void BugLog<T>()
        {
            // 输出参数T所包含的所有bugFix特性的信息
            // 1、根据参数生成 Type
            Type t = typeof(T);
            // 2、先看这个类有没有该特性
            WriteInfo(t, "类");

            // 如:xxxx方法: xx年xx月xx日xxx修复,bug描述:xxxxxx
            // 4、循环方法
            foreach (MethodInfo v in t.GetMethods())
            {
                WriteInfo(v, "方法");
            }

            // 如:xxxx属性: xx年xx月xx日xxx修复,bug描述:xxxxxx
            foreach(PropertyInfo v in t.GetProperties())
            {
                WriteInfo(v, "属性");
            }
        }
        private static void WriteInfo(MemberInfo t, string text)
        {
            Attribute attr = t.GetCustomAttribute(typeof(BugFixAttribute));
            BugFixAttribute attr2 = (BugFixAttribute)attr;
            // 3、判断并输出
            if (attr != null)
            {
                Console.WriteLine($"{t.Name}{text}: {attr2.Time}{attr2.Name}修复,bug描述:{attr2.Message}");
            }
        }
    }
    class BugFixAttribute : Attribute
    {
        public string Name { get; set; }
        public string Time { get; set; }
        public string Message { get; set; }
        public BugFixAttribute(string name, string time, string message)
        {
            Name = name;
            Time = time;
            Message = message;
        }
    }
}
相关推荐
isyangli_blog1 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php
vb2008111 小时前
FastAPI APIRouter
开发语言·python
Benszen1 小时前
KVM虚拟化解决方案
开发语言·perl
会编程的土豆1 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木1 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
杨充2 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
噜噜噜阿鲁~2 小时前
python学习笔记 | 11.3、面向对象高级编程-多重继承
java·开发语言
basketball6162 小时前
Go 语言从入门到进阶:4. 数组和MAP使用方法总结
开发语言·后端·golang
春生野草2 小时前
反射、Tomcat执行
java·开发语言
雪的季节3 小时前
企业级 Qt 全功能项目
开发语言·数据库·qt