Share via


C# and const

When I first started developing programs using C# I had a lot of baggage that I carried over from C++. One of the programming good practices we used to follow in C++ is marking all instance methods (C++ folks insist on calling functions) that do not change the state of an instance as const. To ensure that methods did not accidentally change objects it was not supposed to change the parameters were passed as const as well. Both of these practices are highlighted in the following code

 class MyClass{    int _value;public:    int GetValue() const    {        // the following assignment would have failed to compile        //_value = 5;        return _value;    }    void SetValue(int pVal)    {        _value = pVal;    }}; void show(const MyClass& mc){    // The following line compiles because GetValue is     // marked as const in MyClass    cout << mc.GetValue() << endl;    // the following call would have failed to compile    //mc.SetValue(30);}

In the above code if a maintainer came after a year or two and tried to make any changes in the GetValue method that changed the object it would fail to compile. Similarly if MyClass is in some class library then the const method suffix clearly indicates to the user that the method does not change the object in anyway.

Marking methods with const had an additional benefit as well. In case a methods parameter is marked as const it is not allowed to change the state of the object passed to it. The compiler only allows calls to const methods in this case. However, there are several Gotchas to it, too many for most programmers liking. For example there is nothing to stop a programming from doing the following

 void show(const MyClass& mc){    MyClass& mcNotConst = const_cast<MyClass&>(mc);    mcNotConst.SetValue(20); }

However, I don't think that this is a big issue. Because in a C++ project, the lead's job description includes search for const_cast and fire the guy who sneaked it in. But some gotchas are real bad see https://cpptips.hyperformix.com/cpptips/const_logical

C# unfortunately does not support const methods or const parameters. I always believed that its the duty of a language to be as self-descriptive as possible, const fits well into this even with const_casts lying around.

There is a new feature in C# 2.0 that somewhat helps in a similar scenario. With C#2.0 get and set accessors of a property can be of different accessibility. So you can make the get accessor public and the set protected as follows

 class MyClass{    int _val;    public int Val    {        protectedset { _val = value; }        get { return _val; }    }}

Comments

  • Anonymous
    January 17, 2006
    I come from a C++ background as well, and .NET not have support for consts is something that annoyed me as well.

    Although you mentioned that this new .NET feature "somewhat helps", I think it doesn't. The reason is that it should be possible to use const to protect an object state from changing without changing the object's class definition.

  • Anonymous
    June 21, 2006
    That doesn't fly when the variable is an array:

    <code>
           public Device [] m_devices
           {
               private set
               {
                   m_devices = value;
               }
               get
               {
                   return m_devices;
               }
           }
    </code>

    and

    <code>
               m_devices = new Device[xmlnode.Count];

               for (int i = 0; i < xmlnode.Count; i++)
               {
                   XmlAttributeCollection xmlattrc = xmlnode[i].Attributes;
                   m_devices[i] = new Device(xmlattrc["id"].Value, xmlattrc["dll"].Value, xmlattrc["chipid"].Value);
               }

    </code>

  • Anonymous
    November 09, 2006
    I think "const" is less necessary in languages like C#, because in C++ it is often used to distinguish a refence used for speeding up a function call from a "real" reference.Ex:void f(const std::string &s);void g(std::string s);In the first case, the use of "&" is just to avoid copying the string, and the "const" tells us that. In the second case, we really want to be able to modify "s".So, in C#, with "out" and "ref" keywords, this use of "const" is not needed anymore.But I also miss the "const" used to say that the object will not be modified during the function call.

  • Anonymous
    November 09, 2006
    Sorryvoid g(std::string &s);

  • Anonymous
    April 10, 2008
    siger99, you said "... and the "const" tells us that" - that would be slightly misleading. The const says that "f() will not change the value of the std::string" and has nothing to do with the copying of the string since this is done by using the reference as you said. Another reason C++ would have const is for the user of pointers: void x(int const * p); void y(const int * p); void z (const int const * p); I agree that C# would surely benefit from const method params, though obviously you'd need to avoid situations like: void f (const out int x); since f() needs to change x in-order to conform to the "out".

  • Anonymous
    May 20, 2008
    Still not yet clear idea... Can any one help me out how to handle mutable keyword in c++ when it comes to C#.

  • Anonymous
    March 26, 2009
    The comment has been removed

  • Anonymous
    June 23, 2009
    I'd sure like to be able to mark a C# function (yes, I call them functions) const.