Posted on Jul 16, 2008
One of the things that was hard for me to get past when transitioning from C++ to C# was the lack of a 'const' keyword. Sure C# has 'const' (albeit a weaker version), 'readonly', and "final', but none of them have quite the same semantics as the good ol' C++ const. In C++, I could do something like this:
void DoStuff()
{
const int MaxAmount = CalculateMaxForToday();
if(MaxAmount > 5)
{
// do stuff
}
.
.
.
// do some more stuff
.
.
.
// do stuff at end
Sum += MaxAmount;
}
What I like about that is that I declared MaxAmount as a constant integer and it cannot be changed for its entire lifetime (at least without some semi-major hacking to get around the compiler complaining about it). What I did there was I said that MaxAmount will be constant. I don't intend it to change for its entire scope. I like to think about that as "Intent Programming". I program my intentions into the code. No comment is required. I don't need to say "// MaxAmount shouldn't change". The compiler will enforce the const-correctness for me.
What that also means is that when I get moved off the project and someone else comes on to maintain the code, my intentions will still be enforced. The compiler will enforce them and will protect that variable from accidental or even intentional modification. If the new guy doesn't see MaxAmount being used at the end of the function, he may decide that it's safe to change it. He may decide to re-purpose it it in the middle of that function around the "do some more stuff" section in my example. In C++, the compiler will prevent this. In C#, there's no way to do this. Declaring a variable as 'static readonly' will accomplish this for static variables, but for local variables it just ain't gonna happen.
This is also why I love the 'using' keyword in C#. I have heard that it was tacked on as an afterthought when designing C#, but I love it nonetheless. It allows you to do stuff like:
public void DoDotNetStuff()
{
.
.
.
using (System.IO.Stream stream = wc.OpenRead(url))
{
avatar = image.FromStream(stream);
stream.Close();
}
// can't use stream over here
.
.
.
}
Outside of the using block, stream is out of scope. It's the same as declaring it inside its own scope. You try to use it outside the using block and:
error CS0103: The name 'stream' does not exist in the current context
As long as System.IO.Stream implements IDisposable, you can exactly control the lifetime of your variable and you don't even have to bother messing with the Dispose method. Your variable is scoped, disposed and garbage collected all in one neat and tidy package. You programmed your intent for the usage of that variable right there in the code itself. No comments required.
Sometimes this is called 'Self Documenting Code'. I tend to think of Self Documenting Code as a style of code organization and a usage of long names to describe what the code is doing. With intent programming, you're using the features of the language itself to help declare your intent.
Loading comments...