前言

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

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. 了解Pytorch|Get Started with PyTorch

    一个开源的机器学习框架,加速了从研究原型到生产部署的路径. !pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple import ...

  2. 如何0到1构建DevOps?

    从0到1构建DevOps,首先得弄清楚这个DevOps的受众群体,它的用途到底是什么,解决什么问题,比如Android Studio是为了解决Android应用的开发,3UCS xPlus是为了解决应 ...

  3. Go Micro介绍与入门

    一 什么是Micro? Micro是一个微服务生态系统,致力于提供产品,服务和解决方案,以实现现代软件驱动型企业的创新.我们计划成为任何与微服务相关的事实资源,并期待公司能够利用这项技术为自己的业务. ...

  4. 通过linux-PAM实现禁止root用户登陆的方法

    前言 在linux系统中,root账户是有全部管理权限的,一旦root账户密码外泄,对于服务器而言将是致命的威胁:出于安全考虑,通常会限制root账户的登陆,改为配置普通用户登陆服务器后su切换到ro ...

  5. 三、Python语法介绍

    三.Python语言介绍 3.1.了解Python语言 Python 是1989 年荷兰人 Guido van Rossum (简称 Guido)在圣诞节期间为了打发时间,发明的一门面向对象的解释性编 ...

  6. 最全iOS 上架指南

    一.上架基本需求资料 1.苹果开发者账号(公司已有可以不用申请,需要开通开发者功能,每年 99 美元) 2.开发好的APP 二.证书 上架版本需要使用正式的证书 1.创建证书 Apple Develo ...

  7. Java多线程-线程关键字(二)

    Java中和线程相关的关键字就两:volatile和synchronized. volatile以前用得较少,以后会用得更少(后面解释).它是一种非常轻量级的同步机制,它的三大特性是: 1.保证可见性 ...

  8. SpringBoot 过滤器和拦截器

    过滤器 实现过滤器需要实现 javax.servlet.Filter 接口.重写三个方法.其中 init() 方法在服务启动时执行,destroy() 在服务停止之前执行. 可用两种方式注册过滤器: ...

  9. 重新整理 .net core 实践篇 ———— linux上排查问题实用工具 [外篇]

    前言 介绍下面几个工具: Lldb createdump dotnet-dump dotnet-gcdump dotnet-symbol Procdump 该文的前置篇为: https://www.c ...

  10. 6、将两个字符串连接起来,不使用strcat函数

    /* 将两个字符串连接起来,不使用strcat函数 */ #include <stdio.h> #include <stdlib.h> void strCat(char *pS ...