C#高级特性(反射)
今天来讲解反射的应用:
一、反射是什么?
简诉一下,反射就是.Net Framework 的一个帮助类库,可以获取并使用metadata(元数据清单);说的通俗易懂点,就是不用通过引用,仍然可以使用其他层的类。
二、让我们建一个项目来开始操作吧!!!
1、建立一个控制台应用程序,并建立一个类库,类库里添加一个用户类。
public class UsersInfo
    {
        public string Name { get; set; }
        public bool Sex { get; set; }
        public void CommonMethod()
        {
            Console.WriteLine("我是普通方法");
        }
        public void ParameterMethod(string name)
        {
            Console.WriteLine("我是带参数方法,我叫"+name);
        }
        public void OverrideMethod(int age)
        {
            Console.WriteLine("我是重载方法,我今年"+age);
        }
        public void OverrideMethod(string name)
        {
            Console.WriteLine("我是重载方法,我叫" + name);
        }
        public void GenericityMethod<T>(T t)
        {
            Console.WriteLine("我是泛型方法方法,类型是"+typeof(T));
        }
        private void PrivateMethod()
        {
            Console.WriteLine("我是私有方法");
        }
        public static void StaticMethod()
        {
            Console.WriteLine("我是静态方法");
        }
    }
2、利用反射获取类库,和类
- 第一步引用命名空间
 - 第二步,动态加载类库,写要获取类库的绝对路径
 - 第三步,动态获取类型,写类库的名称和类的名称,不需要后缀
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;//第一步引用命名空间
namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                //第二步,动态加载类库,写要获取类库的绝对路径
                Assembly assembly= Assembly.LoadFile(@"C:\Users\炸天张缺缺\Desktop\Reflection\Reflection.Model\bin\Debug\Reflection.Model.dll");
                //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀
                Type type = assembly.GetType("Reflection.Model.UsersInfo");
                Console.WriteLine(type.Name);
            }
        }
    }
}
3、利用反射获取属性,和属性类型
- 遍历类型的属性集合
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;//第一步引用命名空间
namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                Console.WriteLine("***********************获取类*****************************");
                //第二步,动态加载类库,写要获取类库的绝对路径
                Assembly assembly= Assembly.LoadFile(@"C:\Users\炸天张缺缺\Desktop\Reflection\Reflection.Model\bin\Debug\Reflection.Model.dll");
                //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀
                Type type = assembly.GetType("Reflection.Model.UsersInfo");
                Console.WriteLine(type.Name);
                Console.WriteLine("***********************获取属性*****************************");
                //遍历类型的属性集合
                foreach (var item in type.GetProperties())
                {
                    Console.WriteLine(item.Name+"   "+item.PropertyType);
                }
            }
        }
    }
}
三、获取方法(方法类型比较多,所以单独做个模块来写)
- 创建一个符合类型的对象
 - 指定要获取的方法名称
 - 创建方法,第一个参数,对象,第二个参数,没有则为空
 
1、获取普通方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;//第一步引用命名空间
namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                Console.WriteLine("***********************获取类*****************************");
                //第二步,动态加载类库,写要获取类库的绝对路径
                Assembly assembly= Assembly.LoadFile(@"C:\Users\炸天张缺缺\Desktop\Reflection\Reflection.Model\bin\Debug\Reflection.Model.dll");
                //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀
                Type type = assembly.GetType("Reflection.Model.UsersInfo");
                Console.WriteLine(type.Name);
                Console.WriteLine("***********************获取属性*****************************");
                //遍历类型的属性集合
                foreach (var item in type.GetProperties())
                {
                    Console.WriteLine(item.Name+"   "+item.PropertyType);
                }
                Console.WriteLine("***********************普通方法*****************************");
                object oUser = Activator.CreateInstance(type);//创建一个符合类型的对象
                MethodInfo method = type.GetMethod("CommonMethod");//指定要获取的方法名称
                method.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,没有则为空
            }
        }
    }
}
2、获取带参数的方法
- 指定要获取的方法名称
 - 创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;//第一步引用命名空间
namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                Console.WriteLine("***********************获取类*****************************");
                //第二步,动态加载类库,写要获取类库的绝对路径
                Assembly assembly= Assembly.LoadFile(@"C:\Users\炸天张缺缺\Desktop\Reflection\Reflection.Model\bin\Debug\Reflection.Model.dll");
                //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀
                Type type = assembly.GetType("Reflection.Model.UsersInfo");
                Console.WriteLine(type.Name);
                Console.WriteLine("***********************获取属性*****************************");
                //遍历类型的属性集合
                foreach (var item in type.GetProperties())
                {
                    Console.WriteLine(item.Name+"   "+item.PropertyType);
                }
                Console.WriteLine("***********************普通方法*****************************");
                object oUser = Activator.CreateInstance(type);//创建一个符合类型的对象
                MethodInfo commonMethod = type.GetMethod("CommonMethod");//指定要获取的方法名称
                commonMethod.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,没有则为空
                Console.WriteLine("***********************带参数的方法*****************************");
                MethodInfo parameterMethod = type.GetMethod("ParameterMethod");//指定要获取的方法名称
                parameterMethod.Invoke(oUser, new object[] { "餐餐"});//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
            }
        }
    }
}
3、重载方法
- 指定要获取的方法名称,和参数类型
 - 创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;//第一步引用命名空间
namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                Console.WriteLine("***********************获取类*****************************");
                //第二步,动态加载类库,写要获取类库的绝对路径
                Assembly assembly= Assembly.LoadFile(@"C:\Users\炸天张缺缺\Desktop\Reflection\Reflection.Model\bin\Debug\Reflection.Model.dll");
                //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀
                Type type = assembly.GetType("Reflection.Model.UsersInfo");
                Console.WriteLine(type.Name);
                Console.WriteLine("***********************获取属性*****************************");
                //遍历类型的属性集合
                foreach (var item in type.GetProperties())
                {
                    Console.WriteLine(item.Name+"   "+item.PropertyType);
                }
                Console.WriteLine("***********************普通方法*****************************");
                object oUser = Activator.CreateInstance(type);//创建一个符合类型的对象
                MethodInfo commonMethod = type.GetMethod("CommonMethod");//指定要获取的方法名称
                commonMethod.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,没有则为空
                Console.WriteLine("***********************带参数的方法*****************************");
                MethodInfo parameterMethod = type.GetMethod("ParameterMethod");//指定要获取的方法名称
                parameterMethod.Invoke(oUser, new object[] { "餐餐"});//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
                Console.WriteLine("***********************重载方法int参数*****************************");
                MethodInfo overrideMethodInt = type.GetMethod("OverrideMethod",new Type[] { typeof(int)});//指定要获取的方法名称,和参数类型
                overrideMethodInt.Invoke(oUser, new object[] { 18 });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
                Console.WriteLine("***********************重载方法string参数*****************************");
                MethodInfo overrideMethodStrint = type.GetMethod("OverrideMethod", new Type[] { typeof(string) });//指定要获取的方法名称,和参数类型
                overrideMethodStrint.Invoke(oUser, new object[] { "餐餐" });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
            }
        }
    }
}
4、泛型方法
- 指定要获取的方法名称,和泛型参数类型
 - 创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;//第一步引用命名空间
namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                Console.WriteLine("***********************获取类*****************************");
                //第二步,动态加载类库,写要获取类库的绝对路径
                Assembly assembly= Assembly.LoadFile(@"C:\Users\炸天张缺缺\Desktop\Reflection\Reflection.Model\bin\Debug\Reflection.Model.dll");
                //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀
                Type type = assembly.GetType("Reflection.Model.UsersInfo");
                Console.WriteLine(type.Name);
                Console.WriteLine("***********************获取属性*****************************");
                //遍历类型的属性集合
                foreach (var item in type.GetProperties())
                {
                    Console.WriteLine(item.Name+"   "+item.PropertyType);
                }
                Console.WriteLine("***********************普通方法*****************************");
                object oUser = Activator.CreateInstance(type);//创建一个符合类型的对象
                MethodInfo commonMethod = type.GetMethod("CommonMethod");//指定要获取的方法名称
                commonMethod.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,没有则为空
                Console.WriteLine("***********************带参数的方法*****************************");
                MethodInfo parameterMethod = type.GetMethod("ParameterMethod");//指定要获取的方法名称
                parameterMethod.Invoke(oUser, new object[] { "餐餐"});//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
                Console.WriteLine("***********************重载方法int参数*****************************");
                MethodInfo overrideMethodInt = type.GetMethod("OverrideMethod",new Type[] { typeof(int)});//指定要获取的方法名称,和参数类型
                overrideMethodInt.Invoke(oUser, new object[] { 18 });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
                Console.WriteLine("***********************重载方法string参数*****************************");
                MethodInfo overrideMethodStrint = type.GetMethod("OverrideMethod", new Type[] { typeof(string) });//指定要获取的方法名称,和参数类型
                overrideMethodStrint.Invoke(oUser, new object[] { "餐餐" });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
                Console.WriteLine("***********************泛型方法*****************************");
                MethodInfo genericityMethod = type.GetMethod("GenericityMethod").MakeGenericMethod(new Type[] {typeof(int)});//指定要获取的方法名称,和泛型参数类型
                genericityMethod.Invoke(oUser, new object[] { 123 });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
            }
        }
    }
}
5、私有方法
- 指定要获取的方法名称,指明是父类的私有方法
 - 创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;//第一步引用命名空间
namespace Reflection
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                Console.WriteLine("***********************获取类*****************************");
                //第二步,动态加载类库,写要获取类库的绝对路径
                Assembly assembly= Assembly.LoadFile(@"C:\Users\炸天张缺缺\Desktop\Reflection\Reflection.Model\bin\Debug\Reflection.Model.dll");
                //第三步,动态获取类型,写类库的名称和类的名称,不需要后缀
                Type type = assembly.GetType("Reflection.Model.UsersInfo");
                Console.WriteLine(type.Name);
                Console.WriteLine("***********************获取属性*****************************");
                //遍历类型的属性集合
                foreach (var item in type.GetProperties())
                {
                    Console.WriteLine(item.Name+"   "+item.PropertyType);
                }
                Console.WriteLine("***********************普通方法*****************************");
                object oUser = Activator.CreateInstance(type);//创建一个符合类型的对象
                MethodInfo commonMethod = type.GetMethod("CommonMethod");//指定要获取的方法名称
                commonMethod.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,没有则为空
                Console.WriteLine("***********************带参数的方法*****************************");
                MethodInfo parameterMethod = type.GetMethod("ParameterMethod");//指定要获取的方法名称
                parameterMethod.Invoke(oUser, new object[] { "餐餐"});//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
                Console.WriteLine("***********************重载方法int参数*****************************");
                MethodInfo overrideMethodInt = type.GetMethod("OverrideMethod",new Type[] { typeof(int)});//指定要获取的方法名称,和参数类型
                overrideMethodInt.Invoke(oUser, new object[] { 18 });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
                Console.WriteLine("***********************重载方法string参数*****************************");
                MethodInfo overrideMethodStrint = type.GetMethod("OverrideMethod", new Type[] { typeof(string) });//指定要获取的方法名称,和参数类型
                overrideMethodStrint.Invoke(oUser, new object[] { "餐餐" });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
                Console.WriteLine("***********************泛型方法*****************************");
                MethodInfo genericityMethod = type.GetMethod("GenericityMethod").MakeGenericMethod(new Type[] {typeof(int)});//指定要获取的方法名称,和泛型参数类型
                genericityMethod.Invoke(oUser, new object[] { 123 });//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
                Console.WriteLine("***********************泛型方法*****************************");
                MethodInfo privateMethod = type.GetMethod("PrivateMethod",BindingFlags.Instance|BindingFlags.NonPublic);//指定要获取的方法名称,指明是父类的私有方法
                privateMethod.Invoke(oUser,null);//创建方法,第一个参数,对象,第二个参数,是一个object对象数组,写对应的参数类型
            }
        }
    }
}
6、静态方法
 Console.WriteLine("***********************静态方法*****************************");
                MethodInfo staticMethod = type.GetMethod("StaticMethod");//指定要获取的方法名称
                staticMethod.Invoke(null, null);//不需要实例化,所以第一个可以不写,为空
四、小扩展,反射书写ORM(请原谅我没有注释)
接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NineMonthExam.IDAL
{
    public interface IEFHelpers<T> where T:class
    {
        bool Add(T t);
        bool Remove(int id);
        bool Edit(T t);
        List<T> GetAll();
    }
}
dbhelp类
using NineMonthExam.IDAL;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Data.SqlClient;
using NineMonthExam.Model;
namespace NineMonthExam.DAL
{
    public  class DBHelpers<T> : IEFHelpers<T> where T : BaseModel
    {
        private static  Type type;
        private static string typeName;
        private static string nameStr;
        private static string noIdNameStr;
        private static string sql = "";
        private static StringBuilder addStr = new StringBuilder();
        private static StringBuilder getStr = new StringBuilder();
        private static StringBuilder removeStr = new StringBuilder();
        private static StringBuilder modify = new StringBuilder();
        private static StringBuilder modifyStr = new StringBuilder();
        private static string conStr=ConfigurationManager.ConnectionStrings["conStr"].ConnectionString;
        static DBHelpers()
            {
            type = typeof(T);
            typeName = type.Name;
            nameStr =string.Join(",", type.GetProperties().Select(m=>m.Name));
            noIdNameStr = string.Join(",", type.GetProperties().Where(m=>!m.Name.Equals("Id")).Select(m => m.Name));
            addStr.Append($@"insert into {typeName} ({noIdNameStr}) values ({string.Join(",", type.GetProperties().Where(m => !m.Name.Equals("Id")).Select(m =>$"@{m.Name}"))})");
            getStr.Append($@"select {nameStr} from {typeName}");
            removeStr.Append($@"delete from {typeName}");
            modify.Append($@"update {typeName} set");
            foreach (var item in type.GetProperties().Where(m => !m.Name.Equals("Id")).Select(m => m.Name))
            {
                modify.Append($@" {item}=@{item},");
            }
            string qian = modify.ToString();
            qian = qian.Remove(qian.LastIndexOf(','));
            modifyStr.Append(qian);
            }
        public  bool Add(T t)
        {
            SqlParameter[] parameters = type.GetProperties().Where(m => !m.Name.Equals("Id")).Select(m => new SqlParameter($"@{m.Name}", m.GetValue(t) ?? DBNull.Value)).ToArray();
            sql = addStr.ToString();
            using (SqlConnection conn = new SqlConnection(conStr))
            {
                conn.Open();
                SqlCommand com = new SqlCommand(sql,conn);
                com.Parameters.AddRange(parameters);
                return com.ExecuteNonQuery() > 0;
            }
        }
        public  bool Edit(T t)
        {
            SqlParameter[] parameters = type.GetProperties().Select(m => new SqlParameter($"@{m.Name}", m.GetValue(t)??DBNull.Value)).ToArray();
            string edit=$" where Id = @{type.GetProperty("Id").Name}";
            sql = modifyStr.ToString()+ edit;
            using (SqlConnection conn = new SqlConnection(conStr))
            {
                conn.Open();
                SqlCommand com = new SqlCommand(sql, conn);
                com.Parameters.AddRange(parameters);
                return com.ExecuteNonQuery() > 0;
            }
        }
        private T GetT(SqlDataReader sdr)
        {
            T obj = Activator.CreateInstance(type) as T;
            foreach (var item in type.GetProperties())
            {
                if (sdr[item.Name].GetType() != typeof(DBNull))
                {
                    item.SetValue(obj, sdr[item.Name]);
                }
                else
                {
                    item.SetValue(obj, null);
                }
            }
            return obj;
        }
        public  List<T> GetAll()
        {
            sql = getStr.ToString();
            using (SqlConnection conn = new SqlConnection(conStr))
            {
                conn.Open();
                SqlCommand com = new SqlCommand(sql, conn);
                SqlDataReader reader =com.ExecuteReader();
                List<T> list = new List<T>();
                while (reader.Read())
                {
                    list.Add(GetT(reader));
                }
                return list;
            }
        }
        public  bool Remove(int id)
        {
             string del=$" where Id = {id}";
            sql = removeStr.ToString()+del;
            using (SqlConnection conn = new SqlConnection(conStr))
            {
                conn.Open();
                SqlCommand com = new SqlCommand(sql, conn);
                return com.ExecuteNonQuery() > 0;
            }
        }
    }
}
五、结束语:所有的成功都离不开努力,不要用不公平掩饰你不努力的样子
所有的成功都离不开努力,不要用不公平掩饰你不努力的样子
C#高级特性(反射)的更多相关文章
- Java高级特性——反射机制(第二篇)
		
在Java高级特性——反射机制(第一篇)中,写了很多反射的实例,可能对于Class的了解还是有点迷糊,那么我们试着从内存角度去分析一下. Java内存 从上图可以看出,Java将内存分为堆.栈.方法区 ...
 - PHP高级特性-反射Reflection以及Factory工厂设计模式的结合使用[代码实例]
		
PHP高级特性-反射以及工厂设计模式的结合使用 [结合 Laravel-Admin 代码实例讲解] 利用反射来实现工厂模式的生产而无需创建特定的工厂类 本文地址http://janrs.com/?p= ...
 - Java高级特性——反射机制(第一篇)
		
——何为动态语言,何为静态语言?(学习反射知识前,需要了解动态语言和静态语言) 动态语言 >是一类在运行时可以改变其结构的语言,例如新的函数.对象.甚至是代码可以被引进,已有的函数可以被删除或者 ...
 - Java高级特性—反射和动态代理
		
1).反射 通过反射的方式可以获取class对象中的属性.方法.构造函数等,一下是实例: 2).动态代理 使用场景: 在之前的代码调用阶段,我们用action调用service的方法实现业务即可. 由 ...
 - JAVA高级特性反射和注解
		
反射: 枚举反射泛型注解.html34.3 KB 反射, 主要是指通过类加载, 动态的访问, 检测和修改类本身状态或行为的一种能力, 并能根据自身行为的状态和结果, 调整或修改应用所描述行为的状态和相 ...
 - Java高级特性——反射机制(完结)——反射与注解
		
按照我们的学习进度,在前边我们讲过什么是注解以及注解如何定义,如果忘了,可以先回顾一下https://www.cnblogs.com/hgqin/p/13462051.html. 在学习反射和注解前, ...
 - Java高级特性——反射机制(第三篇)
		
获取类运行时的结构 通过反射获取运行时类的完整结构 Field.Method.Constructor.Superclass.Interface.Annotation >实现的全部接口 >所 ...
 - Java高级特性——反射
		
感谢原文作者:peter_RD_nj 原文链接:https://www.jianshu.com/p/9be58ee20dee 注意:同一个类在JVM中只存在一份字节码对象 概述 定义 JAVA反射机制 ...
 - 云端卫士实战录 | Java高级特性之多线程
		
<实战录>导语 一转眼作为一名Java开发者已经四年多时间了,说长不长说短不短,对于java的感情还是比较深的,主要嘛毕竟它给了我饭吃.哈哈,开个玩笑.今天我想借此机会来和大家聊聊Java ...
 - Spring框架学习[IoC容器高级特性]
		
1.通过前面4篇文章对Spring IoC容器的源码分析,我们已经基本上了解了Spring IoC容器对Bean定义资源的定位.读入和解析过程,同时也清楚了当用户通过getBean方法向IoC容器获取 ...
 
随机推荐
- EF Core 数据过滤
			
1 前言 本文致力于将一种动态数据过滤的方案描述出来(基于 EF Core 官方的数据筛选器),实现自动注册,多个条件过滤,单条件禁用(实际上是参考ABP的源码),并尽量让代码保持 EF Core 的 ...
 - JAVA定时任务原理入门
			
本文适用语言:java 序章:定时任务实现方式 当下,java编码过程中,实现定时任务的方式主要以以下两种为主 spring框架的@Scheduled quzrtz框架 网络上关于这两种框架的实践和配 ...
 - Odoo14 一些好用的开源的模块
			
# odoo14中一些好用的开源的模块 1.intero_reload_form 刷新按钮(页面数据刷新,而不是按F5刷新整个页面) 2.ms_magic_button 弹框下拉选项 3.sessio ...
 - devops-1:代码仓库git的使用
			
devops-gitlab 介绍 gitlab同github.gitee和bitbucket功能一致,都是提供一个存储代码的服务,这里就以gitlab为例,学习一下如何结合git工具使用. 核心组件: ...
 - DolphinScheduler & K8s 在优路科技的实践
			
T 摘要 · 本文通过介绍DolphinScheduler on Kubernetes 在优路科技的实践,阐述了DolphinScheduler如何在云原生时代,更好地助力企业实现高效的数据调度解决方 ...
 - (一)esp32开发环境搭建(VSCode+IDF实现单步调试)
			
保姆级手把手教学视频 https://www.bilibili.com/video/BV1RL411A7CU 前言 因为碰上一个学长,跟他聊了会儿天,推荐我做一点物联网的项目,想来想去,那就用WiFi ...
 - React中useMemo与useCallback的区别
			
useMemo 把"创建"函数和依赖项数组作为参数传⼊入useMemo,它仅会在某个依赖项改变时才重新计算memoized 值.这种优化有助于避免在每次渲染时都进⾏行行⾼高开销的计 ...
 - 关于python如何引用excel文件
			
关于python如何引用excel文件 import pandas as pd #引用pandas库,as:将pandas简写为pd Nowcoder = pd.read_excel("1. ...
 - RabbitMQ 入门系列:3、基础含义:持久化、排它性、自动删除、强制性、路由键。
			
系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...
 - 从C过渡到C++——换一个视角深入数组[初始化](1)
			
从C过渡到C++--换一个视角深入数组[初始化](1) 目录 从C过渡到C++--换一个视角深入数组[初始化](1) 数组的初始化 从C入手 作用域 代码块作用域 文件作用域 原型作用域 函数作用域 ...