c#可以强制转换const吗?

本文关键字:const 转换 | 更新日期: 2023-09-27 18:06:43

如果对象为只读或const,是否可以强制转换该对象使其可写?类似于c++的const_cast

c#可以强制转换const吗?

这在c#中是不可能的,就像在c++中不可能一样。在c++中,如果对象确实是const,你就不能在不调用未定义行为的情况下去掉const并写入它:

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

好吧,我没有说出全部真相。您可以通过反射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.

如果它是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,直到重新编译。

说了这么多,如果你想有一个字段,你想改变,只是不要让它readonly。如果你想让它在类中可变,但从外部不可变,把它设为私有并添加一个只读属性(注意:这与const_cast0字段不同):

class Foo
{
    private int bar;
    public int Bar
    {
        get { return bar; }
    }
}

1这并不能保证,但是它在Microsoft实现中工作。如果你想知道为什么这个hack是有效的,你可以阅读Eric Lippert的解释。一定要阅读readonly关于值类型的答案。不用说,不要在家里这样做

No。该引用或值将为只读。

你可以修改引用的属性,或者只是复制一个值。

不能修改const本身的值。你所能做的就是拿一份拷贝,然后修改它。除非我误解了问题…?

请记住,在c#中const是一个相当有限的关键字,您只能在编译时将某些内容声明为const:

http://msdn.microsoft.com/en-us/library/e6w8fe1b (v = VS.100) . aspx

不知道为什么要改变常量

对象不是只读的,也不是const的,只有变量是。这意味着您只能为这样的变量赋值一次(在const的情况下),或者只能在所有者对象构造完成之前(在readonly的情况下)。

分配给readonly变量的对象仍然可以更改,除非它是不可变的(如string)。

您可以将CSharp的readonly转换掉(相当于c++的const)。CSharp的const可以用constexpr翻译成c++, CC_22不能被丢弃。

要做到这一点,你可以调用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具有相同的含义。