前言

在上一章中介绍了什么是反射:

https://www.cnblogs.com/aoximin/p/16440966.html

正文

上一节讲述反射的基本原理和为什么要用反射,还用反射的优缺点这些。

其二者的本质是一致的,都是先获取到type(元数据)然后在进行创建实例。

下面那个好理解看下上面那个吧。

其实还是调用了activator:

说另外一个故事,是先有对象,后执行构造方法。还是先执行构造方法后有对象呢?到底是编译行为还是运行行为呢?

其实先创建对象,然后再进行构造函数。

而一切初始化其实是在构造函数中。

比如:

public class Cat
{
private string a = "100";
public string b = "100"; public Cat()
{
a = "200";
b = "200";
}
}

那么其.ctor () 为:

计算机远比我们想象的要简单的多,就是开辟一块空间,然后往里面填充数据。 至于定义什么类型,那属于程序的自我管理。

有点扯远了,那么反射的实现也是一样的。

在CreateInstance中:

两者创建对象的原理基本是一致的,反射只是在上面增加了一层动态获取类型(其中包括校验和创建实例的代码生成)。

internal class Program
{
static void Main(string[] args)
{
var type1 = typeof(Cat);
Cat cat = new Cat();
var type2 =cat.GetType(); Assembly assembly = Assembly.GetExecutingAssembly();
var type3 = assembly.GetType("ConsoleApp1.Cat"); var type4 = typeof(Cat); Console.WriteLine($"{type1.GetHashCode()} {type1.GetHashCode()} {type3.GetHashCode()} {type4.GetHashCode()}");
Console.ReadKey();
} static (string name, int age, uint height) GetStudentInfo1()
{
return ("Bob", 28, 175);
}
}

他们的type也是同一个type:

internal class Program
{
static void Main(string[] args)
{
var type1 = typeof(Cat);
Cat cat = new Cat();
var type2 =cat.GetType(); Assembly assembly = Assembly.GetExecutingAssembly();
var type3 = assembly.GetType("ConsoleApp1.Cat"); var type4 = typeof(Cat); Console.WriteLine($"{type1.GetHashCode()} {type2.GetHashCode()} {type3.GetHashCode()} {type4.GetHashCode()}");
Console.ReadKey();
} static (string name, int age, uint height) GetStudentInfo1()
{
return ("Bob", 28, 175);
}
}

值得注意的是typeof 属于语法糖:

现在知道了Type 就包含我们类的元数据了,那么这些元数据到底有哪些呢?

里面包含了描述类的全部信息,有命名空间啊,属性啊,方法啊。这些都是有的。

这些不用去记,用的时候找找看,都有的。

唯一说一个值得的注意的地方哈。

是这样的。有一个BindingFlags这个枚举,可以看到是是一个多选枚举。

然后这样写:

static void Main(string[] args)
{
var type1 = typeof(Cat);
var filter = BindingFlags.Public;
var members = type1.GetMembers(filter); Console.ReadKey();
}

你发现看不到,这是为什么呢?

static void Main(string[] args)
{
var type1 = typeof(Cat);
var members = type1.GetMembers(); Console.ReadKey();
}

来看下是什么样的。

可以看到,这个public string b,其实是public | instance 这样的bindingflag,而不是public。

也就是说默认的是公共且可实例化的。 这个bindingflag的处理,不是或的关系,而是且的关系。

这里也是大家使用多选枚举值得注意的地方,我们的业务上不仅可以用来做或也可以用来做且,它是多选的意思。

如果需要看下反射方法是怎么调用的,可以去查看:System.RuntimeMethodHandle的InvokeMethod,这里面水比较深,选择性观看。

上一节结束了反射,这一节讲了一下反射的大致的行为。下一节反射的常用手段,主要是一些例子。

重学c#系列—— 反射的基本理解[三十三]的更多相关文章

  1. 重学c#系列——字典(十一)

    前言 重学c#系列继续更新,简单看一下字典的源码. 看源码主要是解释一下江湖中的两个传言: 字典foreach 顺序是字典添加的顺序 字典删除元素后,字典顺序将会改变 正文 那么就从实例化开始看起,这 ...

  2. 重学Golang系列(一): 深入理解 interface和reflect

    前言 interface(即接口),是Go语言中一个重要的概念和知识点,而功能强大的reflect正是基于interface.本文即是对Go语言中的interface和reflect基础概念和用法的一 ...

  3. 重学c#系列——对c#粗浅的认识(一)

    前言 什么是c#呢? 首先你是如何读c#的呢?c sharp?或者c 井? 官方读法是:see sharp. 有没有发现开发多年,然后感觉名字不对. tip:为个人重新整理,如学习还是看官网,c# 文 ...

  4. 重学DSP:对于卷积的理解

    最近,我发现自己对于一个事情,如果不给自己一个说服自己的理由,就会出现不能理解,不能记住,以至于不会使用或者“盲目”应用的情况. 但是,我学的这个学科就是应当建立在对信号作用过程的理解上面的. 下面, ...

  5. 重学c#系列——异常(六)

    前言 用户觉得异常是不好的,认为出现异常是写的人的问题. 这是不全面,错误的出现并不总是编写程序的人的原因,有时会因为应用程序的最终用户引发的动作或运行代码的环境而发生错误,比如你用android4去 ...

  6. 重学c#系列——异常续[异常注意事项](七)

    前言 对上节异常的补充,也可以说是异常使用的注意事项. 正文 减少try catch的使用 前面提及到,如果一个方法没有实现该方法的效果,那么就应该抛出异常. 如果有约定那么可以按照约定,如果约定有歧 ...

  7. 重学数据结构系列之——平衡树之SB Tree(Size Blanced Tree)

    学习来源:计蒜客 平衡树 1.定义 对于每一个结点.左右两个子树的高度差的绝对值不超过1,或者叫深度差不超过1 为什么会出现这样一种树呢? 假如我们依照1-n的顺序插入到二叉排序树中,那么二叉排序树就 ...

  8. 重学c#系列——c# 托管和非托管资源(三)

    前言 c# 托管和非托管比较重要,因为这涉及到资源的释放. 现在只要在计算机上运行的,无论玩出什么花来,整个什么概念,逃不过输入数据修改数据输出数据(计算机本质),这里面有个数据的输入,那么我们的内存 ...

  9. 重学c#系列——c# 托管和非托管资源与代码相关(四)

    前言 这是续第三节. 概况垃圾回收与我们写代码的关系: 强引用和弱引用 针对共享 Web 承载优化 垃圾回收和性能 应用程序域资源监视 正文 强引用和弱引用 垃圾回收器不能回收仍在引用的对象的内存-- ...

  10. 重学c#系列——非托管实例(五)

    前言 托管资源到是好,有垃圾回收资源可以帮忙,即使需要我们的一些小小的调试来优化,也是让人感到欣慰的.但是非托管资源就显得苍白无力了,需要程序员自己去设计回收,同样有设计的地方也就能体现出程序员的设计 ...

随机推荐

  1. 关于pwd命令小技巧-确认当前工作目录的绝对路径中是否包含软链接目录名

    Linux中任何一个命令,当你用心研究到深处时,也许总能有着新的发现或者有趣的用途,如下方的pwd命令 对于pwd命令,大家都知道是用于打印当前的工作目录路径,而且是绝对路径 pwd命令两个选项的,默 ...

  2. P5658 [CSP-S2019] 括号树

    对于特殊性质fi=i-1,原图是一条链,注意到当前节点是' ('不会产生贡献,')'才会产生,那么思考怎么的计算这个贡献. ()()():每个位置贡献是0,1,0,2,0,3.答案统计出来就是说0,1 ...

  3. NOI2015 洛谷P1955 程序自动分析(并查集+离散化)

    这可能是我目前做过的最简单的一道noi题目了...... 先对e=1的处理,用并查集:再对e=0查询,如果这两个在同一集合中,则为""NO",最后都满足的话输出" ...

  4. 洛谷P1496 火烧赤壁 (模拟/离散化+差分)

    分析可知:将起点和终点按照从小到大的顺序排序,对答案不会产生影响 所以此时我们得到一种模拟做法: 1 #include<bits/stdc++.h> 2 using namespace s ...

  5. 【强烈推荐】用glob库的一行命令显著加速批量读取处理数据

    在我们气象领域,对数据进行批处理随处可见,尤其是在处理模式数据的时候.为了能让这个过程加速,很多大佬们提出了不同的方法,比如使用numba库进行计算.使用dask库进行并行等等,都是非常好的加速手段. ...

  6. 前端开发日常——CSS动画无限轮播

    近来没有什么值得写的东西,空闲的时候帮前端的同学做了些大屏上的展示模块,就放在这里写写吧,手把手"需求->设计-> 实现",受众偏新手向. 为了直观便于理解, 直接把结 ...

  7. MySQL 全局锁、表级锁、行级锁,你搞清楚了吗?

    大家好,我是小林. 最近重新补充了<MySQL 有哪些锁>文章内容: 增加记录锁.间隙锁.net-key 锁 增加插入意向锁 增加自增锁为 innodb_autoinc_lock_mode ...

  8. MRR和Hits@n

    使用 MRR/Hits@n 评估链路预测 平均倒数秩(Mean reciprocal rank,MRR) MRR是一种衡量搜索质量的方法.我们取一个未被破坏的节点,找到距离定义为相似性分数的" ...

  9. 笔记:Debian下为sublime text建立软链接[像vi一样到处使用]

    先查询sublime-text安装路径 :~$ dpkg -L sublime-text /. /opt /opt/sublime_text ... /opt/sublime_text/sublime ...

  10. Element Ui 安装以及配置

    npm 安装 推荐使用 npm 的方式安装,它能更好地和 webpack 打包工具配合使用. npm i element-ui -S 引入 Element 你可以引入整个 Element,或是根据需要 ...