const,readonly 这些你真的懂吗? 也许会被面试到哦。。。
首先不可否认,这些在面试上会经常被面试官问起,但是你回答的让面试官满意吗?当然如果你知道了这些原理,或许你就不
怕了。既然说到了原理,我们还是从MSDN说起。
一:值得推敲的几个地方
1.先来看看msdn上面对const是怎么说的,我们会看到。不能修改,编译时常量这些关键性信息。

Q: const为什么不能被修改。
A:这个很简单,很多教科书上面都说,当编译器编译时,会将常量的值保存在该程序集的元数据中,下面我们做个实例
看一看。
①:新建一个projectA。
// ProjectA
public class TestClass
{
public const int CTRIP = int.MaxValue;
}
再建一个MainProject,引用下projectA。
using System; class Program
{
static void Main(string[] args)
{
Console.WriteLine(TestClass.CTRIP); Console.Read();
}
}
然后我们把mainproject运行起来。

既然我把mainproject跑起来了,并且也引用了Test.dll,刚才也说了,编译的时候会把常量值保存在程序集的元数据中,那我们
就找一找,打开ILdasm.exe,并且Ctrl+M。

很可惜,我并没有找到Ctrip的符号,也没有找到int.MaxValue,也没有找到所谓的0x7fffffff,倒是找到了一个Assembly
的一些版本信息的元数据,那么这时候你可能会疑惑了,究竟const的值有没有保存到Assembly里面去呢?很简单的一个验证
方法就是,把Mainproject下面bin中的Test.dll删除掉,看看会有怎么样的奇迹发生。


这时候你会发现,既然test.dll都删除了。Demo.exe既然还能运行起来,说明const的值真的是写入到了Assembly里面
去了。不然值从哪里来的呢?
②: 聪明的你应该想到了,既然运行Demo.exe的时候不再加载Test.dll,而是直接从Demo的Assembly里面获取const值,
那是不是会有断层的事情发生,也就是版本不一致的情况,比如我已经修改了const值,然后把编译好的dll拷贝到Mainproject
的bin目录下,直接运行Demo.exe,会不会出现MainProject读不到修改后的const值呢?这里我将const改成 int.MinValue。
下面我们可以试试看。
// ProjectA
public class TestClass
{
public const int CTRIP = int.MinValue;
}


好了,看到上面的结果,就进一步佐证了刚才的说法,const确确实实是保存在Assembly的元数据中,这里还要顺便提示
一下,Enum本质上是const,所以它也存在我刚才说的断层的问题,说到这里,我想你对const的原理应该比较熟悉了,现
在我们来看看Question的问题。既然是元数据,那什么是元数据?“描述数据的数据” 叫做元数据,既然它是基础的描述性数
据,那么在定义好后是决对不能改变的,这个定义时也就是msdn说的编译时,是不是so easy呢?
Q: const为什么要做成静态的,而不是做成实例的
A: 其实通过对第一个Question的分析,很多东西我们应该都会豁然开朗,因为存在断层的问题,那么最好的方法就是const的值
永远也不要变,这样就可以避免问题的发生,既然是永远都不变的东西,当然是跟着“类型”走比跟着“实例”走要好的多,你说
对不对,因为static是个小缓存,没必要new一下才产生。。。
Q: readonly字段只能在ctor中初始化吗?

A:这个问题蛮有意思的,我们知道readonly的意思就是只读字段的意思,我们知道一般的字段具有可读写的功能,
先还是看看编译器怎么说。

从编译器上可以看到,确实readonly的初始化还可以在“变量初始化”的时候进行初始化,那么这样说Question的答案
应该就是否定的,但是真的是如此吗?我们都知道有一个东西叫做“语法糖”,而且经常是编译器提供给我们用的,所以
真正的想看到发生了什么,只能用ILDasm.exe 穿透编译器,看看到底发生了什么。

从IL中可以看到,真的就是编译器的语法糖,本质上都是在ctor中初始化的,所以说,看问题千万不要看表面。
注:Stsfld 用来自计算堆栈的值替换静态字段的值。
const,readonly 这些你真的懂吗? 也许会被面试到哦。。。的更多相关文章
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少. ...
- 你真的懂printf么?
自从你进入程序员的世界,就开始照着书本编写着各种helloworld,大笔一挥: printf("Hello World!\n"); 于是控制台神奇地出现了一行字符串,计算机一句温 ...
- [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?
你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...
- 【转】was mutated while being enumerated 你是不是以为你真的懂For...in... ??
原文网址:http://www.jianshu.com/p/ad80d9443a92 支持原创,如需转载, 请注明出处你是不是以为你真的懂For...in... ??哈哈哈哈, 我也碰到了这个报错 . ...
- javascript的语法作用域你真的懂了吗
原文:javascript的语法作用域你真的懂了吗 有段时间没有更新了,思绪一下子有点转不过来.正应了一句古话“一天不读书,无人看得出:一周不读书,开始会爆粗:一月不读书,智商输给猪.”.再加上周五晚 ...
- 你真的懂ajax吗?
前言 总括: 本文讲解了ajax的历史,工作原理以及优缺点,对XMLHttpRequest对象进行了详细的讲解,并使用原生js实现了一个ajax对象以方便日常开始使用. damonare的ajax库: ...
- “三次握手,四次挥手”你真的懂吗?TCP
“三次握手,四次挥手”你真的懂吗? mp.weixin.qq.com 来源:码农桃花源 解读:“拼多多”被薅的问题出在哪儿?损失将如何买单? 之前有推过一篇不错的干货<TCP之三次握手四次挥手 ...
- 你真的懂 ajax 吗?
前言 总括: 本文讲解了ajax的历史,工作原理以及优缺点,对XMLHttpRequest对象进行了详细的讲解,并使用原生js实现了一个ajax对象以方便日常开始使用. damonare的ajax库: ...
- 【转】先说IEnumerable,我们每天用的foreach你真的懂它吗?
[转]先说IEnumerable,我们每天用的foreach你真的懂它吗? 我们先思考几个问题: 为什么在foreach中不能修改item的值? 要实现foreach需要满足什么条件? 为什么Linq ...
随机推荐
- 【Java每日一题】20161013
package Oct2016; public class Ques1013{ public static void main(String[] args){ new Obj(); } } class ...
- Java---Java的面试题(一)
1.什么是Java虚拟机?为什么Java被称作是"平台无关的编程语言"? Java虚拟机是一个可以执行Java字节码的虚拟机进程.Java源文件被编译成能被Java虚拟机执行的字节 ...
- 说说Java生态圈的那些事儿
文章目录: 1.生态圈概述. 2.说说Java,高级Java,Java生态圈的衍生 3. 说说servlet.servlet容器.比较tomcat.jetty.tomcat.jboss: 1. 哪个项 ...
- Java集合源码分析(一)
Java集合工具包位于Java.util包下,包含了很多常用的数据结构,如数组.链表.栈.队列.集合.哈希表等.学习Java集合框架下大致可以分为如下五个部分:List列表.Set集合.Map映射.迭 ...
- 【转】MySQL的Replace into 与Insert into on duplicate key update真正的不同之处
原文链接:http://www.jb51.net/article/47090.htm 今天听同事介绍oracle到mysql的数据migration,他用了Insert into ..... on ...
- Redis学习笔记1-Redis数据类型
Redis数据类型 Redis支持5种数据类型,它们描述如下: Strings - 字符串 字符串是 Redis 最基本的数据类型.Redis 字符串是二进制安全的,也就是说,一个 Redis 字符串 ...
- 03Mybatis_mybatis框架原理——执行流程
mybatis的框架的原理(执行流程).
- jQuery Wheel 环形菜单插件5种效果演示
很酷的菜单-jQuery Wheel 环形菜单插件5种效果演示在线预览 下载地址 实例代码 <div class="container"> <!-- Top Na ...
- Web Uploader - 功能齐全,完美兼容 IE 的上传组件
文件上传是网站和 Web 应用程序的常用功能,一直没有一款完美的文件上传组件,因此让很多开发人员碰到头疼的浏览器兼容问题. WebUploader 是由 Baidu FEX 团队开发的一款以 HTML ...
- ArcPy之Python介绍
1.Python简介 Python是一种面向对象.解释型计算机程序设计语言;Python是一种简单易学,功能强大的编程语言.它有高效率的高层数据结构,简单而有效地实现面向对象编程.Python简洁的语 ...