开发者

Can C# cast const?

If an object is readonly or const, is it possible to cast that object to make it writable? Someth开发者_Go百科ing similar to C++ const_cast.


It's not possible in C#, just like it's not possible in C++. In C++, if the object is really const, you cannot const_cast the constness away and write to it without invoking undefined behaviour:

struct foo { const int x; };

foo a;
int& b = const_cast<int&>(a.x);
b = 17; // invokes undefined behaviour

A readonly field in C# only means that the field itself cannot be reassigned. It's akin to T *const or T& in C++. You can change the referenced object at will through its members.

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

Well, I'm not telling the whole truth. You can cheat and change readonly fields through reflection1:

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.

If it is a const field however, not even this trick will work.

const fields are hardcoded in assemblies that use them, instead of keeping references to the original assembly:

// 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;

This means that if you recompile A.dll and change the value of Foo.X to 23, B.dll will still use 42 until it is recompiled.

All that said, if you want to have a field that you want to change, just don't make it readonly. If you want it to be mutable by the class, but immutable from the outside, make it private and add a read-only property (note: this is not the same as a readonly field):

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

1This is not really guaranteed, but it works on the Microsoft implementations. If you're wondering why this hack works at all, you can read Eric Lippert's explanation. Be sure to also read the answer about readonly on value types. And it goes without saying, don't do this at home.


No. The reference or value will be read only.

You can however modify the properties of references or you could just make a copy of a value.


You won't be able to amend the value of the const itself. All you can do is take a copy and change that copy. Unless I'm misunderstanding the question...?

Bear in mind that in C# const is quite a limited keyword anyway, you can only declare certain things as const and only at compile time:

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

Not sure why you'd want to mutate a constant.


Objects are not readonly or const, only variables are. That means you can assign a value to such a variable only once (in the case of const) or only until the owner object is constructed (in the case of readonly).

The object assigned to a readonly variable can still be changed, though, unless it's immutable (like string).


You can cast in CSharp readonly away (which is equilant to C++ const). CSharp const could be translated to C++ with constexpr which can't be casted away.

To do so you can call Unsafe.AsRef - which has the same meaning as 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);
   }
}

The same would look in C++ like:

#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();
}

Just in case of static const C++ implementations are allowed to store the data in readonly-memory (which is explicitly allowed by the standard). This is done usually for simple types like int - the reason is that there was no constexpr but the same behaviour was wished - therefore static const has sometimes the same meaning as constexpr.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜