图片 4

Emit学习(4),emit学习

Emit学习(4),emit学习

承接着上一篇, 这一篇主要以堆栈的方式来演示一下,
db数据转换到类中去的一个过程.

一、先看第一张图

图片 1

程序在运行到176行(上一篇贴出的代码)的时候, 就会出现上图中的第一个栈. 

那在此之前, Dapper又做了些什么呢? 抛开Dapper的这种OpCodes的实现方式来说,
我们自己用代码去转换, 实现思路如下:

  1. 首先肯定是要获取, 从db读取出来的那么多列中, 有哪一些是需要转换的吧,
    如果是select * , 那会读取出所有的列, 但是我本身并不需要那么多列, 而且,
    我接收的类, 本身可能并没有那么多的列, 所以, 首先确定有哪些列需要转换,
    以及这些列从db中读取出来是什么类型的. 

  2. 当确定好有效的列之后, 就可以获取类中的构造函数, 已备创建类的时候使用.
    在获取构造函数的时候,
    当然是越简单的构造函数越好.(Dapper中会优先检测标有ExplicitConstructor属性的构造函数,
    然后获取构造函数的参数, 然后初始化参数), 然后就是把这个类new出来.

  3. 到现在, 我们其实就已经能知道source data type 和 target property/feild
    type了, 既然已经两边的类型都已经知道, db数据已经准备好, target
    class也已经new好了, 就可以来实现转换了, 根据类型的不同,
    来使用不同的转换. 值得一提的事, 如果 target class中,
    含有自定义类的属性或者字段, Dapper是不会继续转换的,
    直接给了个null就了事了. 其实Dapper中, 也是可以实现此功能的,
    这部分以后再说.

那么现在回到Dapper里来, 其实他做的工作也是这样子的, 顺序可能稍有不同,
1,2的顺序是可调的. 只是他实现的方式稍有不同而已. 条条大路通罗马,
目的地都是相同的, 不同的是途中的风景.

二、接着第二张图

图片 2

上图中的第一个栈, 是执行完 181行 代码之后, 出现的情况, 180行,
181代码的意思, 其实就是把 reader[index]复制一份到 loc2中,
这个loc2就是前面(161行)声明的, 类型为object的本地变量, 所以,
从堆栈的情况来看, 180行未执行前, 和181行执行完之后的堆栈是一样的.
所以我就不画了. 

在执行Unbox_Any之前, 是已经知道source type和target type了,
并且已经经过判断, 是否能够转换, 然后再通过Unbox_Any来转,
Unbox是拆箱操作, Unbox_Any是拆箱成你需要的类型

上面这两幅图就是正常情况下(int, string, datetime,
double等)的堆栈变化过程了, 应该还是比较能辅助理解的了.

 

http://www.bkjia.com/C\_jc/1171613.htmlwww.bkjia.comtruehttp://www.bkjia.com/C\_jc/1171613.htmlTechArticleEmit学习(4),emit学习 承接着上一篇,
这一篇主要以堆栈的方式来演示一下, db数据转换到类中去的一个过程.
一、先看第一张图 程序在运行到…

承接着上一篇, 这一篇主要以堆栈的方式来演示一下,
db数据转换到类中去的一个过程.

一、先看第一张图

图片 3

程序在运行到176行(上一篇贴出的代码)的时候,
就会出现上图中的第一个栈. 

那在此之前, Dapper又做了些什么呢? 抛开Dapper的这种OpCodes的实现方式来说,
我们自己用代码去转换, 实现思路如下:

  1. 首先肯定是要获取, 从db读取出来的那么多列中, 有哪一些是需要转换的吧,
    如果是select * , 那会读取出所有的列, 但是我本身并不需要那么多列, 而且,
    我接收的类, 本身可能并没有那么多的列, 所以, 首先确定有哪些列需要转换,
    以及这些列从db中读取出来是什么类型的. 

  2. 当确定好有效的列之后, 就可以获取类中的构造函数, 已备创建类的时候使用.
    在获取构造函数的时候,
    当然是越简单的构造函数越好.(Dapper中会优先检测标有ExplicitConstructor属性的构造函数,
    然后获取构造函数的参数, 然后初始化参数), 然后就是把这个类new出来.

  3. 到现在, 我们其实就已经能知道source data type 和 target property/feild
    type了, 既然已经两边的类型都已经知道, db数据已经准备好, target
    class也已经new好了, 就可以来实现转换了, 根据类型的不同,
    来使用不同的转换. 值得一提的事, 如果
    target class中, 含有自定义类的属性或者字段, Dapper是不会继续转换的,
    直接给了个null就了事了. 其实Dapper中, 也是可以实现此功能的,
    这部分以后再说.

那么现在回到Dapper里来, 其实他做的工作也是这样子的, 顺序可能稍有不同,
1,2的顺序是可调的. 只是他实现的方式稍有不同而已. 条条大路通罗马,
目的地都是相同的, 不同的是途中的风景.

二、接着第二张图

图片 4

上图中的第一个栈, 是执行完 181行
代码之后, 出现的情况, 180行, 181代码的意思, 其实就是把
reader[index]复制一份到 loc2中, 这个loc2就是前面(161行)声明的,
类型为object的本地变量, 所以, 从堆栈的情况来看, 180行未执行前,
和181行执行完之后的堆栈是一样的. 所以我就不画了. 

在执行Unbox_Any之前, 是已经知道source type和target type了,
并且已经经过判断, 是否能够转换, 然后再通过Unbox_Any来转,
Unbox是拆箱操作, Unbox_Any是拆箱成你需要的类型

上面这两幅图就是正常情况下(int, string, datetime,
double等)的堆栈变化过程了, 应该还是比较能辅助理解的了.