c# - C# 可以强制转换 const 吗?

标签 c# c++ casting

如果一个对象是只读的或常量的,是否可以将该对象转换为可写的? 类似于 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 *constT&。您可以通过其成员随意更改引用的对象。

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/

相关文章:

c++ - 在 OpenCV 中,有没有比 cv::merge 和 cv::split 更有效地组合/分离图像 channel 的方法?

c++ - 如何删除控制台窗口 C++ 中的滚动条

c - 如何将 void 指针转换为 float 以在 C 函数中使用?

c# - ConnectionStrings 或 AppSettings 的存储库

C# 获取字符串中两个字符之间的字符串

c++ - C++ 协方差何时是最佳解决方案?

c++ - static_cast<int>(foo) 与 (int)foo

c# - ASP.NET MVC 4 中的 ServerManager.OpenRemote 错误 80040154 CLSID {2b72133b-3f5b-4602-8952-803546ce3344}

c# - 使 C# webmethod 的参数可选的最佳方法

c++ - static_cast是否正在创建新的子对象?