Why doesn’t C# have “const”?

I was going to write about why C# doesn't have "const", but Stan Lippman already discussed this in A Question of Const, so now I don't have to.

(And another example of synchronicity: After I wrote up this item and tossed it into the queue, Eric Gunnerson took up the topic as well.

Comments (45)
  1. DrPizza says:

    I may be missing something, but that article hardly seems to explain why C# doesn’t have const. It says that the CLI spec doesn’t allow for a ‘const’-style modifier, and that that leaves us with no good way of implementing that feature of C++.

    It doesn’t seem to put forward any arguments to support the initial decision. To be honest, I’m not aware of any. const is an immensely useful error-catching feature, and it should be retrofitted to the BCL (with all the underlying machinery required to achieve this).

    const correctness is an immensely useful correctness-assisting feature.

    Contrary to Eric Gunnerson’s claims, I’ve not had any negative knock-on effects through using const in large projects, and it’s not the least bit clear to me how such things could arise.

  2. Raymond Chen says:

    Okay, whoever wants to break millions of lines of VB code raise your hand.

    Remember, Mort doesn’t care about "beauty" or "purity". Mort just wants to get his job done.

  3. Cooney says:

    Mort doesn’t care about "beauty" or "purity". Mort just wants to get his job done.

    Yeah, and I have to clean up after mort. Enforce some discipline, please. Besides, it’s not like someone who writes "this.x=x" all over the place is going to blink at casting const away.

  4. Raymond Chen says:

    Everything you make Mort do is viewed by Mort as an obstacle to getting his job done.

    And what’s the point of const if you allow people to cast it away?

  5. Cooney says:

    Everything you make Mort do is viewed by Mort as an obstacle to getting his job done.

    Screw Mort. Every piece of structure and rigor that makes a program capable of lasting more than a month is viewed as an obstacle to getting his job done, because he only cares about the task at hand, not the people who have to do the next task, or the one after that.

    > And what’s the point of const if you allow people to cast it away?

    The alternative is that you either use it everywhere or nowhere and, with third party code, that’s not going to happen.

    Mort is a lost cause – allow him to muddle around and do write his throwaway code, but cater to the people who write code that will still be here in 30 years, and that, sadly includes Mort.

  6. Raymond,

    why is it that the introduction of a ‘const’ modifier to the cli would break a million lines of vb code ?

    i’m not sure i understand that implication.


    thomas woelfer

  7. Raymond Chen says:

    Cooney: Like it or not, 90% of all programmers are Mort. They’re not computer scientists and they are NOT stupid. Professional Morts are infrastructure guys who write scripts to get their job done. To them, computer programming is not an art. It is a skill. Tell them to screw off and you lose pretty much every IT department in the world.

    Thomas: If you introduce "const", then VB code that interops with const will break since VB doesn’t have const. If you go ahead an add const, then you have to retrofit existing VB code to be compatible with it.

    Sub CheckNetworkCard(o As ManagementObject)

    blah blah

    End Sub

    ‘ check all the network cards

    dim o as ManagementObject

    for each o in _

    new ManagementObjectSearcher( _

    "SELECT * FROM Win32_NetworkAdapterConfiguration") _




    Oops, this doesn’t work because the ManagementObjectCollection is now a collection of "const" management objects rather than mutable objects, causing the call to CheckNetworkCard fail with the error "passing const to non-const".

  8. confused soul says:

    Cooney, I did not follow the "this.x=x" reference. Could you please explain?

  9. Trey Nash says:

    Seems to me that the CLI could take the same approach as it has with many other things. Specifically, introduce ‘const’ into the CLI but not force it for CLS. Then, you could have languages implement it if they please.

    I can’t see how that would be completely different than approaches we took in the past for creating COM components that were to be used with VB. We had to be very specific when designing the interface. Handling ‘const’ in the CLI in this manner would product a situation very similar. One would not be able to create interfaces/classes for VB consumption that use ‘const’.

    Sounds fine with me. :-)



    Trey Nash

    Principal Software Engineer

    Macromedia, Inc.

  10. Jack Mathews says:

    When you quote an article with this justification: "My gut feeling is that a majority of C++ applications do not use const well, but I have no real data and base this on informal conversations with students when I use to teach the language."

    Yeah, students are really great at coding, especially in teams. I think that’s a horrible reason to keep something out of a language.

    In my personal experience, in team coding, const has stopped me (and lots of others on my team) from making horrible design decisions and hacks. And while you can cast the const-ness away, ina decently managed environment, someone can see that in a checkin and find out why you felt you needed to do this.

    Anyway, all of these arguments against const-ness make the point about const-ness being hard to put into a project. Yes, it is. But once it’s in place, it really helps a lot.

    Besides, const-ness has been in C++ for awhile and is implemented in the STL. You can interoperate with const-supported libraries FINE without worrying so much about your own const correctness. It’s only when things in the main application support const-correctness that problems occur in projects. So to answer your question:

    "And what’s the point of const if you allow people to cast it away?"

    More type safety, and safety in general. Just because you CAN turn it off doesn’t mean it should never be allowed to be turned on.

  11. Raymond,

    regarding your vb sample: i don’t see why this is a reason to not support constness at all. now, granted that problems might turn up all over the place incase constness was used in the bcl – then don’t use constnes in the bcl.

    why is this a reason to not support constness in c# at all?

    if you’re not going to use constness in the bcl, thats ok with me. but thats not a reason to deny the use of const for everyone, everywhere.


    thomas woelfer

  12. DrPizza says:

    "Okay, whoever wants to break millions of lines of VB code raise your hand. "

    Why would it break any? I’m not proposing const be default (not yet, at least). Since everything will be mutable by default, it should have minimal impact on current code.

    "Remember, Mort doesn’t care about "beauty" or "purity". Mort just wants to get his job done. "

    I want to get my job done too. Fixing other people’s cock ups that the compiler should have cought (would have caught in C++) hinders me.

  13. Raymond Chen says:

    thomas: I guess the question is how important interop is to you. As an OS person, interop is pretty high on my list of important properties of a platform.

  14. DrPizza says:

    And frankly, fuck Mort. Mort is being outsourced to India. I don’t give a toss about him.

  15. Raymond Chen says:

    That’s great customer focus you’ve got there.

  16. B.Y. says:

    It’s a good mental concept, but I don’t see a practical need for const. But still, can someone explain in layman’s terms why there’s no const in C# ?

    Stan Lippman’s article is confusing and sounds very academic. It probably mades sense to language designers only. When people talk about const, they’re not thinking about "transitive closure", whatever that is.

    And after reading it, I’m not sure if he’s for or against const.

  17. Jack Mathews says:

    He’s for adding const ness, saying that the design decision of not adding it is short sighted, like the earlier C++ design decisions (such as putting this at the end of a class).

    Basically the "transitive closure" basically means keeping const-ness throughout an entire tree of operations.

  18. Raymond,

    >> I guess the question is how important interop is to you

    well i disagree: i don’t think this is the question. :-)

    infact, the questions seems to be if it is desirable to force developers to write code that by any means must be interoperable, thus making it impossible to use a programming construct that has proven to be of value for quite some time.

    if a developer chooses to use a specific programming construct and thus creates code that breaks interop with some languages, that should be her decision alone.

    if however, the language does not allow for him to use such a construct, something is wrong.

    i subscribe to interop beeing a great goal for you guys. however, knowing that my code will never be called from any developer outside my company, that goal isn’t necessarily mine.

    if everything .net has to be interoperable with everything else .net – no matter who wrote what part of what code – than why support multiple languages in the first place?

    well, i guess we won’t find a common point of view here ;) – that nonwithstanding, pls. let me thank you for your very helpful blog anyways.


    thomas woelfer

  19. Cooney says:

    I recently inherited some java code that uses this construct (among other sins). Many classes are constructed like this:

    class Foo {

    int x;

    Foo(int x) {




    This is ugly, but it works. The problem comes when the class grows large and x is moved, renamed, or removed. This.x=x still compiles, but it does nothing, and the careless programmer won’t notice it among 2000 lines. When I got the code, there were places where this was occuring, and I found out about it because I went through the codebase and cleaned up about 500 warnings, leaving stuff like this. X had been renamed to x’ – something similar to x, but not x, but the code (mostly) worked, so I couldn’t just change it, as it might break something. It’s been a few months now, and the code is getting better. Soon I will be able to determine whether I can remove this.

    Re: customer focus, I want tools that allow me to write better code and make my job easier. Adding const to an interface doesn’t require the the caller support it, and using a non-const interface when I have const objects requires that I either cast, or write a compatibility layer. I prefer this to not having const, as I have a better chance of isolating bugs to some other guy’s code. What I’d really like to do in the ugly case is write some code that casts to const and then checks for modifications (at least in debug mode). How that would work is rather thorny.

    Oh yeah, and the much maligned Mort in this case is originally from China, according to the never sufficiently damned source control software.

  20. Raymond Chen says:

    Okay, so you’re all arguing that "const" could be put into the "C#-specific" part of the CLR. If you’re willing to accept that you’re going to do a boatload of const-casting then good for you.

  21. Sean says:

    I remember the topic of the different theoretical developer roles at MS awhile ago — is there a place to get more info on these roles? it’s great stuff ;)

    I like the discussion of Mort and specifially the post that contained: "Every piece of structure and rigor that makes a program capable of lasting more than a month is viewed as an obstacle to getting his job done, because he only cares about the task at hand, not the people who have to do the next task, or the one after that."

    Unfortunately the flip side of Mort is that -because- Mort programs with a Hammer, places where the lack of structure and rigor introduce hard-to-find bugs, Mort then tends to blame the makers of his development environment (in this case, MS) for creating such a POS product…

    it’s a viscous circle…

  22. Nathan says:

    I like this:

    public class Foo {

    private int x;

    public Foo(int x) {

    this.x = x;



    We could always go back to prefixing everything with "m_" or "_".

    public class Foo {

    private int m_x;

    public Foo(int x) {

    this.m_x = x;



    I would think that if people are deleting, or renaming parameters to methods/constructors, then they would bother to see if the particular parameter in question is being used within the method body.

    I think this.x = x, isnt ugly, rather elegant. It draws a direct correlation between the parameter, the the variable it is being assigned to. I religously use the "this" keyword, but in the last 2 years of C# programming I have never had an incident where this.x = x, has cuased my problems.

    Rather this one messes me up:

    public class Foo {

    private int x;

    public int X {

    get { return this.X; }

    set { this.x = value; }



    See the infinite loop in that one hehe. What makes it worse, is that sometime Intellisense get reall happy about autocomplete, and inserts X, when you want x.

  23. Nathan,

    >> I think this.x = x, isnt ugly, rather elegant


    thomas woelfer

  24. Cooney says:

    Whether you like this.x=x or not, consider this: you now have two variables with the same name, distinguished by scope. If one changes, then odds are that you won’t generate an error. If you use the m_ prefix approach, then that same change won’t compile. I prefer this way because it means that my code tends to behave by default – this particular programming error is caught by the compiler at the time of the commision.

  25. Sean says:

    I used to be a this.x=x programmer until I started doing x = x which is far more elegant IMHO…

    and yes, I’d regularly get those stack overflow exception errors since I’d have those properties like Nathan explains..

    fixes that and makes me more productive..;)

  26. Don’t worry. I’m sure that the next "ultimate solution" "be all and end all" solution to every programming problem on the face of the earth will actually do this right.

    Or maybe the one after that.

  27. Aarrgghh says:

    Raymond says:

    > "And what’s the point of const if you

    > allow people to cast it away?"

    In C++, you can cast away ANY part of the type system, not just const. C++ static type checking is optional in general. You can #undef STRICT, too. Does that mean STRICT is pointless? Nope.

    It’s more compelling to argue that dealing with const can be a pain in the ass, but in a world full of buffer overruns and other miseries brought on by Convenient Coding Practices, I’d think people would realize that convenience for the programmer can equal massive inconvenience for the user. Those of us who sell the stuff for money actually have an obligation to get it right. Mort’s a different story: He IS a user, so he can sacrifice quality for convenience however he likes. He’s not programming; he’s playing make-believe, like a kid on an amusement park ride pretending to be an astronaut. If MS products spoil the illusion for him, he’ll spend his money with a vendor who’ll give him a more satisfactory play experience.

    With programming languages, one size does not fit all and it never will.

  28. Eisbaer says:

    Who the hell is Mort??

  29. Aarrgghh says:


    JavaScript would be perfect if there were an implementation with I/O as convenient as Perl, and Perl would be perfect if it were as friendly to data structures as JavaScript.

    Thank God there’s enough interpreted languages to go around.

  30. Jason G says:

    I can’t seem to find the article right now, but it was from a while back and talked about why const wasn’t in C#/CLR.

    The story I remember was that a large chunk of developers took const as a guarantee and made security choices based on const presence.

    Once that error in judgment was found out, const got pulled to prevent more people from assuming that const guaranteed you anything.

    In other words, the risk of a security hole was considered worse than not including const.

    Bottom line, do you want const to mean something? If so, it has to be supported by the CLR so that it can’t be violated (that is the point behind managed code, correct?) Making const inviolable is actually really hard to do. It can’t be simple compile time checking, it has to do runtime checking also.

    If you want it in C#, work on getting it added to the CLR first.

    There are also lots of other gotchas. For instance, there are fundamental differences between C++ and C#/managed code in how things are stored.

    For instance, if the object I pass in as a const parameter returns a property that is another object, is that returned object a const object also?

    Does it depend on whether it is a field in the object begin returned?

    Is the const’ness a property of each and every reference made on an object, requiring the object to store a list of which references are (not) const and somehow know how it’s being accessed?

    It just gets really, really ugly.

  31. The .NET team was always somewhat… schizoid on whether or not they wanted to actually have real compatibility with VB.

    The changes made to create VB.NET were a radical enough of a change from VB6 (and prior versions of the language) that there should have been no question of compatibility at all (in which case, const should have been supported).

    However, the .NET team was (seemingly) going through some upper management issues at the time – certainly in terms of making a decision and sticking with it – and on a weekly (if not daily) basis, the decision as to whether or not design errors in VB6’s framework should be duplicated for VB.NET.

    A stunning example of this is the Masked Edit control – which, if you look at the VB6 one, is absolutely fine, except that its behavior is not defined for non-Latin languages (or combining diacritics), and the fact that the set of fields you can specify are assymmetrical (prizes for finding the one case which isn’t handled in the field specificatiosn).

    People went back and forth several times on whether or not it should be absolutely 100% backwards compatible with the VB6 control (warts and all), or whether it should be made more compatible – all to satisfy the old VB6 developer who ended up not being the target customer anyway. Combine absentee PMs with a politically-green software developer (me), and hey presto – the control didn’t even end up shipping. But right until the end, it was flipping and flopping between "Do it like VB6" and "Do it right".

    (Mind you, there were several other examples of sloppiness like this and other abortive meanderings in the design of the framework – the whole VSForms thing being a prime example).

    C# supports features which VB doesn’t – that’s why the CLR is the "***common**** language runtime" – it’s a subset which all of the supported languages can talk to. So there’s nothing per-se stopping C# from having a proper const modifier. But utimately, the moment the choice was made to break with existing VB code, that choice should have been carried out to its logical conclusion. If we’re still talking about "hey, it’ll break VB developers’ code", then obviously there’s a mixed message on that subject getting out there.

  32. DrPizza says:

    It hardly helps MS to have the likes of Mort cobbling together crappy buggy applications.

    Mort’s const correctness errors are *bugs*. It might be that his language doesn’t catch those bugs. That doesn’t mean that they don’t exist.

    And frankly, this entire line of argument is idiotic, as VB has undergone breaking change after breaking change after breaking change. You’ve never cared about Mort before. Why start now?

  33. ATZ Man says:

    It sounds like a redux of how edit-and-continue was not "seen" to be important, even though it can only be implemented in the core by MSFT (can’t be implemented by 3rd party add-on).

    I don’t understand how VB interop is a breaker for const. Firstly, we’ve had C++ coders supplying DLL’s for use from VB for "eons", so obviously a language with const in it is practically interoperable with one that doesn’t have it, for some definition of "practical."

    Secondly, if there is some concern about system libraries being used by const and in-const-ant languages alike, there is **obviously** at least one viable way to make that work, and the minimal effort there is to have non-const-correct system libraries. You could even add a functioning const keyword to VB.NET at the same moment as making non-const-correct libraries.

    A pragmatic strategy consisting of enabling const in the system and the languages, while leaving the libraries as they are, would allow Morts to keep dodging malpractice suits with their broken code while simultaneously allowing professionals to practice with the care they want to take.

  34. Raymond Chen says:

    If you are happy with an ineffective const, you can always make your own ConstAttribute and slap it on anything you want.

    I wonder how many people would have complained if C# did have const but also allowed you to modify const objects (by casting away const). I suspect a lot of people would have said, "Stupid Microsoft. Here was their big chance to fix one of the biggest bugs in C++ and they blew it. Const is useless. Would have been better if it had never been born."

  35. Matthew Lock says:

    Do people really believe stricter languages will get Mort writing better code? I have maintained OO code written by Mort and frankly it would have been better if Mort had just stuck to old procedural code.

  36. Jason G says:


    It’s not that they don’t want to give programmers the tools to be more expressive in their intent, but they do have a short amount of time to get their features in.

    As Raymond said, you can still have a ConstAttribute that can target parameters/methods, and then code verification tools to do checks.

  37. Ben Hutchings says:

    Mort should be using a language that is dynamically typed, so he doesn’t have to worry about declaring things const or not. A naive programmer isn’t going to be able to write super-efficient code anyway so a bit more run-time type checking isn’t going to hurt. Besides which, dynamically typed languages like Python are *fun*.

  38. Wondering says:

    const relies on external libraries using it appropriately in prototypes. Otherwise, you’re left wondering "was the lack of const and oversight or is there a chance that it may change the argument in some circumstances".

    One example, off the top of my head, CLSIDFromString(). Anyone seen the source code?

  39. Norman Diamond says:

    Why allow static declarations at file scope when they can always be evaded by passing a pointer?

    Why allow variables to have types when the type system can always be evaded by use of *(other_type*)& ?

    Why have while and for statements when if and goto can do them all?

    Why allow variables to have long names when that makes it possible for names to say the opposite of the actual meaning of the variable?


    Answer: Because it is beneficial to allow good programmers to use those features for their intended purposes. Good programmers appreciate the help in catching their unintended mistakes.

    Yes C’s definitions (more than three actually) for the keyword "const" are screwed up, but proper use brings great benefits.

    By the way VC header files define all kinds of Microsoft macros that equate to very little in the end. VC headers could add stuff like this:

    #define readonly const

    #define immutable const

    Bugs will still be possible (a poor programmer’s practice or good programmer’s typo could still put readonly on a variable or put immutable on the pointed-to type of a pointer parameter). But the intended documentary purpose would be there.

  40. DrPizza says:

    "Okay, so you’re all arguing that "const" could be put into the "C#-specific" part of the CLR. If you’re willing to accept that you’re going to do a boatload of const-casting then good for you. "

    No. It can only work properly if put into the base infrastructure. It needs to be in the BCL. It needs to be in the metadata. It needs to be everywhere.

    And it’s not clear to me why there’ll be a boatload of const casting. I don’t have a boatload of const casting in C++; the only time I const_cast is when interoperating with legacy C void*-using APIs; as I normally const my locals (just because they’re called variables doesn’t mean they’re meant to vary) occasionally a const_cast is required.

  41. Jack Mathews says:

    > I suspect a lot of people would have said, "Stupid Microsoft. Here was their big chance to fix one of the biggest bugs in C++ and they blew it. Const is useless. Would have been better if it had never been born." <<

    Justifying arguments with hypothetical "well people would bitch the other way too" doesn’t really help.

  42. Raymond Chen says:

    Well, seeing as the commenters here can’t even agree on what "const" should do, it seems clear that whatever decision was taken, somebody’s going to write that.

  43. That’s not synchronicity, that’s a meme.

Comments are closed.