如果一个对象是只读的或常量的,是否可以将该对象转换为可写的? 类似于 C++ const_cast 的东西。
最佳答案
这在 C# 中是不可能的,就像在 C++ 中是不可能的一样。在 C++ 中,如果对象确实是 const,则不能在不调用未定义行为的情况下const_cast
去掉常量并写入它:
struct foo { const int x; };
foo a;
int& b = const_cast<int&>(a.x);
b = 17; // invokes undefined behaviour
C# 中的readonly
字段仅表示该字段本身不能被重新分配。它类似于 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
好吧,我并没有说出全部真相。可以通过反射作弊修改readonly
字段1:
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.
但是,如果它是一个 const
字段,即使这个技巧也不起作用。
const
字段在使用它们的程序集中被硬编码,而不是保留对原始程序集的引用:
// 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;
这意味着,如果您重新编译 A.dll 并将 Foo.X
的值更改为 23,则 B.dll 在重新编译之前仍将使用 42。
总而言之,如果您想要更改某个字段,请不要将其设置为只读
。如果您希望它在类中可变,但在外部不可变,请将其设为私有(private)并添加一个只读属性(注意:这与 readonly
字段不同):
class Foo
{
private int bar;
public int Bar
{
get { return bar; }
}
}
1这个 is not really guaranteed ,但它适用于 Microsoft 实现。如果您想知道为什么这个 hack 有效,您可以阅读 Eric Lippert's explanation 。请务必阅读有关 readonly
on value types 的答案。不用说,不要在家里这样做。
关于c# - C# 可以强制转换 const 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7175019/