在C#中不可能,就像在C++中一样。在C++中,如果对象确实是const的,你不能使用const_cast
去掉const属性并且写入它,否则会引发未定义的行为:
struct foo { const int x; };
foo a;
int& b = const_cast<int&>(a.x);
b = 17; // invokes undefined behaviour
readonly
字段在 C# 中仅表示该字段本身无法重新分配。这类似于 C++ 中的 T *const
或 T&
。您可以通过其成员随意更改所引用的对象。
class Foo { public int x; }
class Bar { public readonly Foo y = new Foo(); }
Bar a = new Bar();
a.y.x = 3; // valid
a.y = new Foo(); // invalid
好的,我并没有说出全部真相。你可以通过反射1来作弊并更改readonly
字段:
typeof(string).GetField("Empty").SetValue(null, "bar");
// this effectively makes string.Empty equal to "bar", with disastrous consequences
// It requires full trust though.
// Obviously, it's evil.
// Assembly A.dll
public class Foo { public static const int X = 42; }
// Assembly B.dll
int y = Foo.X;
// this is the equivalent to:
int y = 42;
Foo.X
的值更改为 23,则 B.dll 将仍使用 42,直到重新编译 B.dll。readonly
。如果您希望该字段可变但对外部是不可变的,请将其设置为私有,并添加只读属性(注意:这与 readonly
字段不同):class Foo
{
private int bar;
public int Bar
{
get { return bar; }
}
}
1这并不是完全保证,但它在Microsoft实现上有效。如果您想知道为什么这个黑科技能够奏效,可以阅读Eric Lippert的解释。一定要读关于值类型上的readonly
的答案。而且不用说了,不要在家里尝试。
readonly
更像Bar*const
而不是const Bar*
。 - Yakov Galka你将无法修改 const
的值本身。你所能做的只是复制一份并更改该副本。除非我误解了问题...?
请记住,在 C# 中,const
是一个相当有限的关键字,你只能在编译时声明某些特定的东西为 const
:
http://msdn.microsoft.com/en-us/library/e6w8fe1b(v=VS.100).aspx
不确定为什么你想要改变一个常量。
不会。引用或值将只读。
但是,您可以修改引用的属性,或者只需复制一个值。
在CSharp中,您可以使用readonly
进行转换(相当于C++中的const
)。 CSharp中的const
可以使用constexpr
转换为C++,但无法强制转换。
要这样做,您可以调用Unsafe.AsRef
- 它与C++中的const_cast
具有相同的含义:
using System;
class App{
static readonly int i = 42;
static void Main(){
Console.WriteLine(i);
System.Runtime.CompilerServices.Unsafe.AsRef(i) = 777;
Console.WriteLine(i);
}
}
在C++中,它看起来是这样的:
#include <iostream>
class App{
public:
static inline int iStorage= 42;
static inline const int& i = iStorage;
static void Main(){
std::cout << i << '\n';
*const_cast<int*>(&i) = 777;
std::cout << i <<'\n';
}
};
int main(){
App::Main();
}
如果允许在static const
的C++实现中将数据存储在只读内存中(这是标准明确允许的),那么就需要进行相关处理。
通常对于像int
这样的简单类型执行此操作-原因是没有constexpr,但希望具有相同的行为-因此,static const
有时与constexpr
具有相同的含义。
对象不是只读或常量,只有变量才是。这意味着您只能将值分配给这样的变量一次(在const
的情况下)或仅在所有者对象构造之前(在readonly
的情况下)。
分配给readonly
变量的对象仍然可以更改,除非它是不可变的(例如string
)。