1. 基本了解

1.1 反射概述

文字说明

审查元数据并收集关于它的类型信息的能力称为反射,其中元数据(编译以后的最基本数据单元)就是一大堆的表,当编译程序集或者模块时,编译器会创建一个类定义表,一个字段定义表,和一个方法定义表等

反射提供了封装程序集、模块和类型的对象(Type 类型),可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。如果代码中使用了属性,可以利用反射对它们进行访问

实际上

反射是微软封装的一个帮助类库:using System.Reflection;

1.2 反射用途

  • 使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例
  • 使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法
  • 使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulicprivate)和实现详细信息(如abstractvirtual)等;使用TypeGetConstructorsGetConstructor方法来调用特定的构造函数
  • 使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulicprivate)和实现详细信息(如abstractvirtual)等;使用TypeGetMethodsGetMethod方法来调用特定的方法
  • 使用FiedInfo了解字段的名称、访问修饰符(如publicprivate)和实现详细信息(如static)等,并获取或设置字段值。
  • 使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
  • 使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值
  • 使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等

1.3 反射常用类

反射是一个程序集发现及执行的过程,通过反射能够得到 .exe.dll 等程序集内部的信息,使用反射能够看到一个程序集内部的接口、类、方法、字段、属性、特性等信息

类型 描述
Assembly 通过此类能够载入操纵一个程序集,并获取程序集内部信息
FieldInfo 该类保存给定的字段信息
MethodInfo 该类保存给定的方法信息
MemberInfo 该类是一个基类,定义了EventInfo,FieldInfo,MethodInfo,PropertyInfo的多个公用行为
Module 该类能够使你能訪问多个程序集中的给定模块
ParameterInfo 该类保存给定的參数信息
PropertyInfo 该类保存给定的属性信息

2. Assembly 程序集对象

2.1 对象简介

官方文档

程序集包含模块、模块包含类型,而类型包含成员。 反射提供封装程序集、模块和类型的对象。 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型

其它文档

System.Reflection.Assembly:表示一个程序集

程序集是代码进行编译是的一个逻辑单元,把相关的代码和类型进行组合,然后生成PE文件(例如可执行文件.exe和类库文件.dll

由于程序集在编译后并不一定会生成单个文件,而可能会生成多个物理文件,甚至可能会生成分布在不同位置的多个物理文件,所以程序集是一个逻辑单元,而不是一个物理单元;即程序集在逻辑上是一个编译单元,但在物理储存上可以有多种存在形式

对于静态程序集可以生成单个或多个文件,而动态程序集是存在于内存中的

在C#中程序集处处可见,因为任何基于.NET的代码在编译时都至少存在一个程序集(所有.NET项目都会默认引用mscorlib程序集)

程序集包含了两种文件:可执行文件(.exe文件)和 类库文件(.dll文件)

在VS开发环境中,一个解决方案可以包含多个项目,而每个项目就是一个程序集

2.2 应用程序结构

包含应用程序域(AppDomain),程序集(Assembly),模块(Module),类型(Type),成员(EventInfo、FieldInfo、MethodInfo、PropertyInfo) 几个层次

2.3 静态方法

常用静态方法

方法 返回值类型 描述
Assembly.Load Assembly 加载相对路径下指定名称程序集
Assembly.LoadFile Assembly 根据全路径获取指定程序集
Assembly.LoadFrom Assembly 根据全路径获取指定程序集

2.4 实例方法,属性

常用实例属性

属性 属性值类型 描述
assembly.FullName string 获取程序集的显示名称
assembly.Location string 获取程序集的完整路径(全名称)
assembly.DefinedTypes IEnumerable 获取定义在程序集中类型集合
assembly.Modules IEnumerable 获取定义在程序集中模块集合

常用实例方法

方法 返回值 描述
assembly.GetTypes() Type[] 获取程序集中定义的类型数组
assembly.GetType() Type 获取程序集中定义的类型
assembly.GetExportedTypes() Type[] 获取程序集中定义的所有公共类型(类,接口,枚举等)
assembly.CreateInstance() object 根据传入类型创建类型实例

2.5 示例:加载程序集

方式一:Loadc2 引用了 Helper,有引用关系

using System;
using System.Reflection;
using Helper; namespace c2
{
class Program
{
static void Main(string[] args)
{
// 相对路径下加载指定名称程序集文件
Assembly assembly = Assembly.Load("Helper");
}
}
}

示例二:LoadFilec2taskdao无引用关系

using System;
using System.Reflection; namespace c2
{
class Program
{
static void Main(string[] args)
{
// 根据全名称(路径+文件名.后缀)下加载指定名称程序集文件
Assembly assembly =
Assembly.LoadFile(@"E:\SolutionZX\taskdao\bin\Debug\taskdao.dll");
}
}
}

示例三:LoadFromc2taskdao无引用关系

using System;
using System.Reflection; namespace c2
{
class Program
{
static void Main(string[] args)
{
// 根据全名称(路径+文件名.后缀)下加载指定名称程序集文件
Assembly assembly =
Assembly.LoadFrom(@"E:\SolutionZX\taskdao\bin\Debug\taskdao.dll");
}
}
}

示例四:根据类型创建类型实例,c2taskdao无引用关系

dynamic 类型为动态类型,使用时编译器不会检查(运行时检查)

using System;
using System.Reflection; namespace c2
{
class Program
{
static void Main(string[] args)
{ // 根据全名称(路径+文件名.后缀)下加载指定名称程序集文件
Assembly assembly =
Assembly.LoadFrom(@"E:\SolutionZX\taskdao\bin\Debug\taskdao.dll"); // object _t = assembly.CreateInstance("task1dao.task1");
// 报错,object类型识别不出Show方法,因为C#是强类型语言
// _t.Show(); dynamic _t = assembly.CreateInstance("task1dao.task1");
_t.Show();
}
}
}

2.6 获取类型

获取普通类型

Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.UserInfo");

获取泛型类型

Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.UserInfo`1"); // UserInfo`1 英文状态下数字1左边符号,参数个数

3. Type 类型

在C#中可以理解为一个类对应一个Type对象

3.1 实例属性,方法

实例属性

属性 属性值类型 描述
type.Name string 获取类型名称(类名)
type.FullName string 获取类全名(命名空间+类名称)
type.Namespace string 获取类所在的命名空间
type.Assembly string 获取类所在程序集名称
type.BaseType Type 获取基类(父类)
type.IsSubclassOf(Type parent) bool type是否是parent的子类
type.IsInstanceOfType(object o) bool o是否是type类的对象
type.IsClass bool 获取对象类型是否是类
type.IsInterface bool 获取对象类型是否是接口
type.IsNotPublic bool 获取对象类型是否公开
type.IsAbstract bool 获取对象类型是否是抽象的
type.IsSealed bool 获取对象类型是否是密封的
type.IsArray bool 获取对象类型是否是数组
type.IsEnum bool 获取对象类型是否是枚举

实例方法

方法 返回值类型 描述
type.GetMembers() MemberInfo[] 获取类型中所有公共成员
type.GetMethods() MethodInfo[] 获取所有公共方法(包含基类)
type.GetConstructors() ConstructorInfo[] 获取类型中所有公共构造函数
type.GetFields() FieldInfo[] 获取所有公共字段
type.GetProperties() PropertyInfo[] 获取所有公共属性
type.GetInterfaces() Type[] 获取所有公共接口
type.MakeGenericType(...) Type 设置泛型类,泛型参数类型
type.GetMember(...) MemberInfo[] 多个,获取公共成员(不常用)
type.GetMethod(...) MethodInfo 单个,获取公共方法
type.GetConstructor(...) ConstructorInfo 单个,获取公共方法
type.GetField(...) FieldInfo 单个,获取公共字段
type.GetProperty(...) PropertyInfo 单个,获取公共属性
type.GetInterface(...) Type 单个,获取公共接口

3.2 操作示例一

public class Base
{ }
public interface Inta { } public interface Intb { } public class UserInfo<A> : Base, Inta, Intb
{
#region 公共构造函数
public UserInfo()
{
Console.WriteLine("无参构造方法...");
}
public UserInfo(int id)
{
Console.WriteLine("1个参数构造方法");
}
#endregion #region 私有构造函数
private UserInfo(string name) { }
#endregion #region 公共字段
public string code;
#endregion #region 私有字段
private string msg;
#endregion #region 公共属性
public int id { get; set; }
#endregion #region 公共方法
public void Print()
{
Console.WriteLine("无参数实例方法");
} public void Show()
{
Console.WriteLine("无参数重载实例方法");
}
public void Show(int id)
{
Console.WriteLine("有参数重载实例方法-" + id.ToString());
}
#endregion #region 公共静态方法
public static void Statc() { }
#endregion #region 私有方法
private void GetM()
{
Console.WriteLine("无参数私有方法");
}
private void GetM(int i)
{
Console.WriteLine("有参数私有方法-" + id.ToString());
}
#endregion #region 公共泛型方法
public void GenericC(A a)
{
Console.WriteLine("公共泛型无参方法:" + a.ToString());
}
public void GenericS<T>()
{
Console.WriteLine("公共泛型无参方法");
} public void GenericsA<T>(A a, T t)
{
Console.WriteLine("公共泛型有参方法:" + t.ToString() + "\t" + a.ToString());
} #endregion
}

通过类获得对应的Type

Type type = typeof(UserInfo);

通过 Assembly 对象,通过类的fullname类获得Type对象

Assembly assem = Assembly.LoadFrom(@"E:\SolutionRP\DMO\bin\Debug\DMO.dll");
Type type = assem.GetType("DMO.UserInfo");

综合示例

Type type = typeof(UserInfo);
Console.WriteLine("类型名:" + type.Name);
Console.WriteLine("类全名:" + type.FullName);
Console.WriteLine("命名空间名:" + type.Namespace);
Console.WriteLine("程序集名:" + type.Assembly);
Console.WriteLine("模块名:" + type.Module);
Console.WriteLine("基类名:" + type.BaseType);
Console.WriteLine("是否类:" + type.IsClass); MethodInfo method = type.GetMethod("Show");//获得实例的方法 Console.WriteLine("类的公共成员:"); MemberInfo[] memberInfos = type.GetMembers();//得到所有公共成员
foreach (var item in memberInfos)
{
Console.WriteLine("成员类型:" + item.MemberType + "\t成员:" + item);
}

3.3 示例二:获取公共方法

一:获取所有公共成员

static void Main(string[] args)
{
Type type = typeof(UserInfo); Console.Write("获取所有公共成员:");
MemberInfo[] members = type.GetMembers();
Console.WriteLine(members.Length); Console.Write("获取所有公共方法(包含基类):");
MethodInfo[] methods = type.GetMethods();
Console.WriteLine(methods.Length); Console.Write("获取所有公共构造函数:");
ConstructorInfo[] constructors = type.GetConstructors();
Console.WriteLine(constructors.Length); Console.Write("获取所有公共字段:");
FieldInfo[] fields = type.GetFields();
Console.WriteLine(fields.Length); Console.Write("获取所有公共属性:");
PropertyInfo[] properties = type.GetProperties();
Console.WriteLine(properties.Length); Console.Write("获取所有公共接口:");
Type[] interfaces = type.GetInterfaces();
Console.WriteLine(interfaces.Length);
}

根据名称获取公共成员(不常用)

MemberInfo[] memberInfo1 = type.GetMember("code");
MemberInfo[] memberInfo2 = type.GetMember("Show");
Console.WriteLine(memberInfo1.Length);
Console.WriteLine(memberInfo2.Length);

根据名称获取公共方法

// 获取公共方法(非重载方法)
MethodInfo methodInfo1 = type.GetMethod("Print");
Console.WriteLine(methodInfo1.Name); // 获取公共重载方法,根据参数顺序,类型,个数获取
// 1.调用有一个int类型参数的重载方法
MethodInfo methodInfo2 = type.GetMethod("Show", new Type[] { typeof(int) });
// 2.调用无参数重载方法(不可传null)
MethodInfo methodInfo3 = type.GetMethod("Show", new Type[0]);
Console.WriteLine(methodInfo3.Name);

根据参数的类型,数量,顺序返回指定构造方法

// 返回无参公共构造方法
ConstructorInfo constructor1 = type.GetConstructor(new Type[0]); // 返回有一个int类型参数的公共构造方法
ConstructorInfo constructor2 = type.GetConstructor(new Type[] { typeof(int) });

获取类型公共字段

FieldInfo fieldInfo1 = type.GetField("code");
Console.WriteLine(fieldInfo1.Name);

获取类型公共属性

PropertyInfo propertyInfo1 = type.GetProperty("id");
Console.WriteLine(propertyInfo1.Name);

3.4 示例三:获取静态方法

3.5 示例四:获取泛型方法

获取泛型方法

Assembly assembly = typeof(Program).Assembly;

// 获取有一个泛型参数的类
Type type = assembly.GetType("c2.UserInfo`1"); // 指定泛型参数类型
Type generictype = type.MakeGenericType(new Type[] { typeof(int) }); object oType = Activator.CreateInstance(generictype);

4. MethodInfo 方法

一个 MethodInfo 表示一个方法(公共,私有,静态,构造)

4.1 实例属性,方法

实例属性

属性 属性值类型 描述
methodInfo.Name string 方法名称
methodInfo.ReturnType Type 获取方法返回值类型
methodInfo.IsConstructor bool 是否是构造方法
methodInfo.IsAbstract bool 是否为抽象方法
methodInfo.IsPrivate bool 是否为私有方法
methodInfo.IsPublic bool 是否为公共方法
methodInfo.IsStatic bool 是否为静态方法
methodInfo.IsVirtual bool 是否为虚方法
methodInfo.IsGenericMethod bool 是否为泛型方法

实例方法

方法 返回值 描述
methodInfo.Invoke(...) object 调用非泛型方法
methodInfo.GetParameters() ParameterInfo[] 获取方法参数数组

4.2 操作示例一

获取调用非泛型非重载无参数方法,无参数方法第二个参数可传null,但不推荐

Type type = typeof(UserInfo);
object oType = Activator.CreateInstance(type); MethodInfo methodInfo = null; methodInfo = type.GetMethod("Print"); methodInfo.Invoke(oType,new object[0]);
methodInfo.Invoke(oType, null);

获取调用非泛型重载无参数方法,无参数方法第二个参数可传null,但不推荐

Type type = typeof(UserInfo);
object oType = Activator.CreateInstance(type); MethodInfo methodInfo = null; methodInfo = type.GetMethod("Show",new Type[0]);
methodInfo.Invoke(oType,new object[0]);
methodInfo.Invoke(oType, null);

获取调用非泛型重载有参数方法,多个参数用逗号隔开,参数类型,个数,顺序必须相同

Type type = typeof(UserInfo);
object oType = Activator.CreateInstance(type); MethodInfo methodInfo = null; methodInfo = type.GetMethod("Show", new Type[] { typeof(int) });
methodInfo.Invoke(oType, new object[] { 1 });

4.3 操作示例二

获取泛型方法与获取普通方法一致,泛型参数按从左到右顺序传入,方法参数类型与泛型参数类型一致

调用公共泛型无参方法

// 获取泛型方法
MethodInfo methodInfo = type.GetMethod("GenericS");
// 指定泛型方法参数
MethodInfo genericmethod = methodInfo.MakeGenericMethod(new Type[] { typeof(int) }); genericmethod.Invoke(oType, null);

调用公共泛型有参方法

MethodInfo methodInfo = type.GetMethod("GenericsA");
MethodInfo genericsmethod =
methodInfo.MakeGenericMethod(new Type[] { typeof(int), typeof(string) });
genericsmethod.Invoke(oType, new object[] { 1 });

调用公共泛型类的有参方法,泛型类中的泛型参数与泛型方法的泛型参数一致

static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.UserInfo`1"); Type generictype = type.MakeGenericType(new Type[] { typeof(int) }); object oType = Activator.CreateInstance(generictype); MethodInfo methodInfo = generictype.GetMethod("GenericC");
methodInfo.Invoke(oType, new object[] { 1 });
}

调用公共泛型类的有参方法,泛型类中的泛型参数与泛型方法的泛型参数不一致

static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.UserInfo`1"); Type generictype = type.MakeGenericType(new Type[] { typeof(int) }); object oType = Activator.CreateInstance(generictype); MethodInfo methodInfo = generictype.GetMethod("GenericsA");
MethodInfo genericsmethodinfo =
methodInfo.MakeGenericMethod(new Type[] { typeof(string) });
genericsmethodinfo.Invoke(oType, new object[] { 2, "af" });
}

5. ConstructorInfo 构造函数

5.1 实例属性,方法

实例方法

方法 返回值类型 描述
constructor.Invoke(...) object 执行构造函数

5.2 操作实例一

public class User
{
public User()
{
Console.WriteLine("无参构造函数");
}
public User(string n)
{
Console.WriteLine("有参构造函数:" + n);
}
}

调用构造函数

static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.User"); object oType = Activator.CreateInstance(type); ConstructorInfo constructor = type.GetConstructor(new Type[0]);
constructor.Invoke(oType, null); ConstructorInfo constructor1 = type.GetConstructor(new Type[] { typeof(string) });
constructor1.Invoke(oType, new object[] { "liai" }); ParameterInfo[] parameters = constructor1.GetParameters();
Console.WriteLine(parameters.Length);
}

6. PropertyInfo 属性

6.1 实例属性,方法

实例属性

属性 属性值类型 描述
property.Name string 获取属性名称
property.CanRead bool 获取属性是否可读
property.CanWrite bool 获取属性是否可写
property.PropertyType Type 获取属性类型

实例方法

方法 返回值类型 描述
property.SetValue(...) void 设置对象属性
property.GetValue(...) object 获取对象属性值

6.2 操作实例一

获取公共属性

// 获取所有
PropertyInfo[] propertys = type.GetProperty(); // 获取指定
PropertyInfo property = type.GetProperty("no");

获取属性,设置属性值,获取属性值

class Program
{
static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.Order"); object oType = Activator.CreateInstance(type); PropertyInfo property = type.GetProperty("no"); property.SetValue(oType,1); var value = property.GetValue(oType);
Console.WriteLine(value);
}
} public class Order
{
public int no { get; set; }
}

7. FieldInfo 字段

7.1 实例属性,方法

实例属性

属性名 属性值类型 描述
field.Name string 获取字段名称
field.Is... bool 获取字段是否为...
field.FieldType Type 获取字段类型

实例方法

7.2 操作实例一

获取字段

class Program
{
static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.Order"); object oType = Activator.CreateInstance(type); FieldInfo field = type.GetField("name"); FieldInfo[] fields = type.GetFields();
}
} public class Order
{
public string name;
}

获取值,设置值

class Program
{
static void Main(string[] args)
{
Assembly assembly = typeof(Program).Assembly;
Type type = assembly.GetType("c2.Order"); object oType = Activator.CreateInstance(type); FieldInfo field = type.GetField("name");
field.SetValue(oType, "libai"); var value = field.GetValue(oType);
Console.WriteLine(value);
}
} public class Order
{
public string name;
}

8. 扩展补充

8.1 加载程序集

获得当前【应用程序域】中的所有程序集

Assembly[] ass = AppDomain.CurrentDomain.GetAssemblies();

获得当前对象所属的类所在的程序集

Assembly assembly = this.GetType().Assembly;

Assembly.LoadFileAssembly.LoadFrom的差别

  • LoadFile 方法用来载入和检查具有同样标识但位于不同路径中的程序集,但不会载入程序的依赖项
  • LoadFrom 不能用于载入标识同样但路径不同的程序集

创建实例对象

此方法的作用与 new 一个实例对象相同

Activator.CreateInstance(type)

8.2 Module 程序集模块

Assembly assembly = Assembly.Load("mscorlib");//加载程序集
Module module = assembly.GetModule("CommonLanguageRuntimeLibrary");//得到指定模块
Console.WriteLine("模块名:" + module.Name);
Type[] types = module.FindTypes(Module.FilterTypeName, "Assembly*");
foreach (var item in types)
{
Console.WriteLine("类名:" + item.Name);//输出类型名
} Console.Read();

8.3 BindingFlags说明

枚举值 描述
BindingFlags.Instance 对象实例
BindingFlags.Static 静态成员
BindingFlags.Public 指可在搜索中包含公共成员
BindingFlags.NonPublic 指可在搜索中包含非公共成员(即私有成员和受保护的成员)
BindingFlags.FlattenHierarchy 指可包含层次结构上的静态成员
BindingFlags.IgnoreCase 表示忽略 name 的大小写
BindingFlags.DeclaredOnly 仅搜索 Type 上声明的成员,而不搜索被简单继承的成员
BindingFlags.CreateInstance 表示调用构造函数。忽略 name。对其他调用标志无效

8.4 属性应用:ORM

简易实现

public Order Find(int id)
{
string sql = "select id,name,createTime from order where id = " +id; Type type = typeof(Order);
object oOrder = Activator.CreateInstance(type); using (SqlConnection connection = new SqlConnection("constr"))
{
SqlCommand cmd = new SqlCommand(sql,connection);
connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
foreach (var prop in type.GetProperties())
{
prop.SetValue(oOrder,prop.Name);
}
}
} return (Order)oOrder;
}
// DTD
public class Order
{
public int no { get; set; }
public string name { get; set; }
public DateTime createTime { get; set; }
}

泛型版本

public T Find<T>(int id) where T : BaseEntity
{
string sql = "select id,name,createTime from order where id = " + id; Type type = typeof(T);
object oOrder = Activator.CreateInstance(type); using (SqlConnection connection = new SqlConnection("constr"))
{
SqlCommand cmd = new SqlCommand(sql, connection);
connection.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
foreach (var prop in type.GetProperties())
{
prop.SetValue(oOrder, prop.Name);
}
}
} return (T)oOrder;
} public class BaseEntity { }
public class Order:BaseEntity
{
public int no { get; set; }
public string name { get; set; }
public DateTime createTime { get; set; }
}

02.反射Reflection的更多相关文章

  1. [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦

    [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...

  2. [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程

    [.net 面向对象程序设计进阶] (20) 反射(Reflection)(上)利用反射技术实现动态编程 本节导读:本节主要介绍什么是.NET反射特性,.NET反射能为我们做些什么,最后介绍几种常用的 ...

  3. [整理]C#反射(Reflection)详解

    本人理解: 装配件:Assembly(程序集) 晚绑定:后期绑定 MSDN:反射(C# 编程指南) -----------------原文如下-------- 1. 什么是反射2. 命名空间与装配件的 ...

  4. CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)

    CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction) 开始 如图所示,本文围绕GLSL里的sam ...

  5. 代理(Proxy)和反射(Reflection)

    前面的话 ES5和ES6致力于为开发者提供JS已有却不可调用的功能.例如在ES5出现以前,JS环境中的对象包含许多不可枚举和不可写的属性,但开发者不能定义自己的不可枚举或不可写属性,于是ES5引入了O ...

  6. Golang 反射reflection

    反射reflection 反射可大大提高程序的灵活性,使得interface{}有更大的发挥余地 反射使用TypeOf和ValueOf函数从接口中获取目标对象信息 反射会将匿名字段作为独立字段(匿名字 ...

  7. C# 反射(Reflection)技术

    本文参考自C#反射(Reflection)详解,纯属学习笔记,加深记忆 在介绍反射前,先介绍一个重要的知识点         .Net应用程序是由程序集(Assembly).模块(Module).类型 ...

  8. C#反射(Reflection)详解

    1. 什么是反射2. 命名空间与装配件的关系3. 运行期得到类型信息有什么用4. 如何使用反射获取类型5. 如何根据类型来动态创建对象6. 如何获取方法以及动态调用方法7. 动态创建委托 1.什么是反 ...

  9. C# 反射Reflection——反射反射程序员的快乐

    一.什么是反射 反射Reflection:System.Reflection,是.Net Framework提供的一个帮助类库,可以读取并使用metadata. 反射是无处不在的,MVC-Asp.Ne ...

随机推荐

  1. DOS命令行(8)——netsh-网络配置命令行工具

    netsh 介绍与语法 netsh(Network Shell) 是一个windows系统本身提供的功能强大的网络配置命令行工具,可用来显示与修改当前正在运行的计算机的网络配置(如:IP地址.网关.D ...

  2. 初学springboot

    现在总是与数据库和前端打交道,让我觉得好厌烦,还是喜欢敲代码.最近问了几个朋友,都说潮流要学springCloud,然后学springCloud又要先学springboot,所以这段时间我会慢慢把sp ...

  3. ubuntu 18.4LTS 安装12.1.6赛门铁克防病毒系统

    创建/tools/ 文件夹,并将需要的软件包上传到该目录下 # mkdir -p /tools/ && cd /tools/ # tar -xzvf chang.tar.gz # cd ...

  4. 6、安装kvm虚拟机

    6.1.虚拟机开启虚拟化: 6.2.检查linux虚拟机cpu是否开启了虚拟化: egrep -o 'vmx|svm' /proc/cpuinfo vmx 6.3.安装kvm管理和安装kvm虚拟机的软 ...

  5. CentOS-Docker安装Redis(单点)

    下载镜像 $ docker pull redis 创建目录 $ mkdir -p /usr/redis/data 运行镜像 $ docker run --restart=unless-stopped ...

  6. Docker:docker创建容器时报错:WARNING: IPv4 forwarding is disabled. Networking will not work.

    创建容器时报错: WARNING: IPv4 forwarding is disabled. Networking will not work. # docker run -it -p 30001:2 ...

  7. bson的类型

    BSON是JSON的扩展数据类型

  8. mybatis框架学习第一天

    三层架构: 表现层:用于展示数据 业务层:处理业务需求 持久层:和数据库交互的 3.持久层技术解决方案: JDBC技术: Connecction PreparedStatement ResultSet ...

  9. 『心善渊』Selenium3.0基础 — 25、unittest单元测试框架

    目录 1.unittest基本简介 2.unittest基本概念 (1)unittest核心的四个概念 (2)如何创建一个测试类 (3)test fixture常用的四个方法 (4)unittest编 ...

  10. 可搜索加密技术 - 学习笔记(二)- 预备知识:HMAC-SHA256函数

    由于在之后的算法中会用到HMAC-SHA256函数,这里先简单对其进行一个介绍. 一.HMAC算法 什么是HMAC算法? HMAC是密钥相关的哈希运算消息认证码(Hash-based Message ...