[C#基础知识] ReadOnly关键字修饰的变量可以修改,只是不能重新分配
转自:http://www.cnblogs.com/sujiantao/archive/2011/12/19/2289357.html
MSDN 官方的解释
首先要明确一点:更改!=重新分配(赋值)
对于简单类型(如int),更改是等于重新赋值,因为默认操作符只有=, 但于对于复杂类型,就不一定了。
例如:
对于class类型,修改其字段属性值。
对于集合类型,增加,移除,清空内容。
我们经常在微软的代码中发现readonly的如下类似的用法:
1 public interface IA { }
2 public class A1 : IA { }
3 public class A2 : IA { }
4
5 public static class AContainer
6 {
7 private static readonly Dictionary<string, IA> Items = new Dictionary<string, IA>();
8 public static Dictionary<string, IA> As{ get { return Items; } }
9 }
然后在外部可以修改AContainer
1 class Program
2 {
3 static void Main()
4 {
5 Console.WriteLine(AContainer.As.Count);
6 AContainer.As.Add("A1", new A1());
7 Console.WriteLine(AContainer.As.Count);
8 AContainer.As.Add("A2", new A2());
9 Console.WriteLine(AContainer.As.Count);
10 // we can remove all the item of the collection
11 AContainer.As.Clear();
12 Console.WriteLine(AContainer.As.Count);
13 Console.ReadKey();
14 }
15
16 }
输出:

结论:
可以在外部(非声明和构造函数)对readonly的变量进行修改内容操作。
微软示例和开源代码中用的一种开发扩展的方式就是使用静态的ReadOnly集合容器类,在其中包括默认的实现,然后允许用户在开发中进行添加或替换。
如MVC3中的 ModelBinderProviders,ViewEngines都是类似的实现。
当然我们还可以通过非常规手段(反射,操作内存)来改变readonly的值。
例如反射
1 using System;
2 using System.Reflection;
3
4 namespace SOVT
5 {
6 public class Foo
7 {
8 private readonly int bar;
9 public Foo(int num) { bar = num; }
10 public int GetBar() { return bar; }
11 }
12
13 class Program
14 {
15 static void Main()
16 {
17 Foo foo = new Foo(123);
18 Console.WriteLine(foo.GetBar());
19 FieldInfo fieldInfo = typeof(Foo).GetField("bar", BindingFlags.Instance | BindingFlags.NonPublic);
20 if (fieldInfo != null)
21 fieldInfo.SetValue(foo, 567);
22 Console.WriteLine(foo.GetBar());
23 Console.ReadKey();
24 }
25 }
26 }
输出

[C#基础知识] ReadOnly关键字修饰的变量可以修改,只是不能重新分配的更多相关文章
- ReadOnly关键字修饰的变量可以修改,只是不能重新分配
MSDN 官方的解释 readonly 关键字是可以在字段上使用的修饰符.当字段声明包括 readonly 修饰符时,该声明引入的字段赋值只能作为声明的一部分出现,或者出现在同一类的构造函数中. ...
- 10.使用final关键字修饰一个变量时...
10.使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 答:引用不能变,不能将引用再次指向另一个新的对象,但引用所指向的对象中的内容是可以改变的. 补充: 1.对于基本类型,f ...
- 【Java面试题】2 Java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?超详细解析
/* * 问题:使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变 * 答: * 使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的 ...
- 使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的.例如,对于如下语句:final StringBuffer a=new StringBuffer( ...
- java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
java中使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? 是引用对象的地址值不能变,引用变量所指向的对象的内容是可以改变. final变量永远指向这个对象,是一个常量指针,而 ...
- 使用final关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?
使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的.例如,对于如下语句: final StringBuilder a=new StringBuilder ...
- 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第6节 static静态_12_静态static关键字修饰成员变量
创建一个学生类 定义成员变量,无参构造,全参构造.成员变量的getter和setter 所在教室必须是一样的,定义所在教室 下面来创建两个学生 只给one的room赋值了.two的教室并没有赋值.都输 ...
- 静态static关键字概述和静态static关键字修饰成员变量
static关键字 概述 关于 static 关键字的使用,它可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单是属 于某个对象的.也就是说,既然属于类,就可以不靠创建对象来调用了 ...
- C语言基础知识(一)——关键字
存储类别说明符变量:auto.register.static.extern._Thread_local.typedef 存储类型限定符:const.volatile.restrict._Atomic ...
随机推荐
- floyd算法
求两个顶点间的最短距离,直觉是这样的问题可以用尝试和枚举的办法来求解,这显然可行,但是我们可以换个方式来看待这个问题,比如, 可以这样描述,“在给定的点集(编号为1~k,k=图中所有的顶点数量)中,i ...
- OpenCV学习笔记——OpenCV安装
关于OpenCV安装 1.下载和安装OpenCV SDK 在官网:http://opencv.org/上找到OpenCV windows版下载 . 后得到一个 opencv-2.X.X.exe的文件, ...
- 性能测试知多少---系统架构分析 转自https://yq.aliyun.com/articles/35147?spm=5176.100239.blogcont24251.8.lS96At
摘要: 有些事儿一旦放一放就难再拾起来,突然发现<性能测试知多少>这个系列两月没更新,关键时我都不知道啥时候放下的,总容易被各种技术所吸引走,如饥似渴的想学更多的东西,这几天一直有朋友问我 ...
- geohash-net实现
基于c#语言 geohash算法基本实现源码,参见: https://github.com/sharonjl/geohash-net , 源码中具体包含如下方法: String CalculateAd ...
- 常用Web Service汇总(天气预报、时刻表等)
现成的Web Service中有很多很好用的,比如天气预报,IP地址搜索,火车时刻表等等.本文汇总的一些常用Web Service,希望对大家有所帮助. AD: ================= ...
- docker网络配置方法总结
docker启动时,会在宿主主机上创建一个名为docker0的虚拟网络接口,默认选择172.17.42.1/16,一个16位的子网掩码给容器提供了65534个IP地址.docker0只是一个在绑定到这 ...
- setTimeout()与setInterval()
一.setTimeout与setInterval的用法(http://www.css88.com/archives/5804) setTimeout是超时调用,javascript是一个单线程的解析器 ...
- ubuntu修改主机名
ubuntu修改主机名 主机名在/etc/hostname文件中了,只在打开这个文件进行修改,重启计算机即可. 一.查看主机名 $ hostname #查看主机名 cdyemail ...
- CDN(翻译)
http://dojotoolkit.org/documentation/tutorials/1.10/cdn/index.html 从CDN上加载dojo模块时非常有用的.从CDN上加载Dojo并同 ...
- Spring 事务注解 错误问题
碰到个问题,在一个springmvc项目中,设置好事务,然后在service上添加@Transactional注解,只要一添加这个注解,该service就无法被spring创建成功, error cr ...