Eri*_*ert 24
是的,在C#中有几种方法可以做到这一点.
首先,什么是"变量"?变量是存储位置.局部变量,方法的形式参数(以及索引器,构造函数等),静态和实例字段,数组元素和指针解引用都是变量.
某些变量可以声明为"只读"."readonly"变量只能通过声明中的初始化程序或构造函数更改一次.只有字段声明才能读取; C#不支持用户声明的只读本地.
对只读变量有一些限制,有助于确保C#的正常操作不会引入突变.这可能会导致一些意想不到的结果!看到
http://ericlippert.com/2008/05/14/mutating-readonly-structs/
详情.
一些当地人也是有效的.例如,当你说using(Stream s = whatever)嵌入语句里面的那个时using你不能改变s的值.这种限制的原因是为了防止您创建要处置的资源的错误,然后在处置变量s的内容时处置不同的资源.最好是一样的.
(不幸的是,C#中存在错误,涉及处理资源是结构类型的情况,结构体有一个方法可以改变结构,而局部变量是或者不是匿名函数或迭代器块的封闭本地;由于情景模糊不清,修复可能会破坏,我们还没有采取任何措施,等待进一步分析.)
在声明的局部变量foreach声明也有效readonly-该变量的变化通过循环值每一次,但你不能改变它的值.
无法创建只读形式参数,数组元素或指针取消引用.
有多种方法可以"中断"只读限制并写入一个应该只读的变量.如果您有足够的权限,可以使用Reflection或不安全的代码来破解CLR的任何安全限制.如果你这样做会伤害,不要这样做; 有了这些权力,就有责任知道你在做什么,做得对.
您可以使用自定义setter滚动自己(但Object除非必须,否则请不要使用,请选择正确的类):
private Object myObj = null;
private Boolean myObjSet = false;
public Object MyObj
{
get { return this.myObj; }
set
{
if (this.myObjSet) throw new InvalidOperationException("This value is read only");
this.myObj = value;
this.myObjSet = true;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:
这并不会阻止类内部更改私有字段.
您可以创建自己的通用类来提供此功能,但这可能有点过分.
public class SetValueOnce<T>
{
public bool _set;
private T _value;
public SetValueOnce()
{
_value = default(T);
_set = false;
}
public SetValueOnce(T value)
{
_value = value;
_set = true;
}
public T Value
{
get
{
if(!_set)
throw new Exception("Value has not been set yet!");
return _value;
{
set
{
if(_set)
throw new Exception("Value already set!");
_value = value;
_set = true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13497 次 |
| 最近记录: |