Introduction
This article aims to provide a good fundamental explanation and analogy for the following general areas:
- Scope
- Use of semi-colons and curly-braces
- Code Structure
- Syntax
- Methods
- Variables
- Brief note on Access Modifiers
This article assumes that you (the reader) have at least made some attempt at a C# Windows Forms program, even if that attempt is just crating the project in Visual Studio and running it.
Background
A few weeks ago a friend of mine started to learn to program. While he has been successfully picking up the basics doing the (very good) MSDN tutorials, he was struggling to get his head around the use of semi-colons (;) and curly braces ({}). So I wrote the following, originally document, to help explain it to him.
So lets start somewhere, what is “scope”?
The word “scope” is a little unclear to the beginner. So
instead of using the word “scope”, we will call it a “box” and by box, I mean,
a box.
So what are “boxes”?
Obvious isn’t it? A box contains things, and so do scopes.
(I know I said I wouldn’t use that ghastly word but don’t worry). So boxes
(scopes) contain things. Now when you are in a house full of boxes, the biggest
container is the house. It is a global container. It contains all the boxes and
programming has just the same, it has a house, a global container. This global
container is, in fact, the programming language itself. So for example C# is
the global container.
So what about these boxes (scopes)? Where do they fit into
this?
Well naturally in a house you will have different types of
boxes all labelled (named) something different and you will have boxes within
boxes within boxes. So in the same way you have different types of scope, named
different things and you can have scopes within scopes within scopes etc.
So the outermost box is always a namespace box. You will see this in C# highlighted blue. The
namespace scope also has a name associated with it, and that is the name of our
box. A namespace with a different name is a different box. So for example the
following would define a namespace box (scope) called HelloWorld:
namespace HelloWorld
{
}
Aaah! What are those curly braces? Well, a box has sides
right? The things that say how big the box is and where it is. Well the curly
braces are just that, they are sides. The curly braces say where the box
(scope) starts and where it ends. The {
brace is an opening brace, a start brace, the brace that says “the top of the
box is here”. The } brace says “the
bottom of the box is here. This is where it stops.”
So curly braces define where the box is. Now within the
namespace box you have class boxes. Classes define object types. So for
instance I could create a class called Plane like so:
class Plane
{
}
And that defines a type called Plane. This allows me to
create objects of type Plane later. In other words, it allows me to create
specific planes later, but all with the same structure. So class boxes go
inside the namespace boxes, but what goes inside class boxes?
There are two main types of thing that go inside class
boxes. These are variables and methods. Now variables have a type (such as
integer, bool or Plane) and variables store data. You define a variable, then
you set it to a value and then you do stuff with it but the variable itself
doesn’t do anything, it just gets passed around as a bit of data that other
lines of code can look at and go “Hey look that’s the data I want!”. You define
a variable by saying what type it is, then what its name is. E.g.
int MyInteger1;
Now why oh why is there a semi colon? Well lines of code
come in two types; Simple lines (statements) or complex (multiline, enclosing
statements). The latter usually ends up defining a scope. So simple lines of
code end in a semi-colon, complex, multiline statements or lines of code that
define scope do not need a semi colon, they use curly braces. This is about as
simple as it gets. So lets carry on and we’ll give more examples later.
But I haven’t set MyInteger1 to anything!? No, you don’t
need to initially. You can define a variable and then the totally separate thing
is setting it to have a value. So how do we set a variable to something? Well
hopefully you know this is the assignment operator “=”. To set something you do “thing I want to set = the thing I
want it to be set to” or in better terms “assign variable to value” which in
code is “variable = value”. But these are simple lines so they need a semi
colon. So the full thing becomes:
MyInteger1 = 10;
Where we have defined MyInteger1 earlier and 10 is the value
we set it to. You will also see combined definition and assignment statements
that give variables an initial value e.g.
int MyInteger = 10;
But hold on a second, I’ve said variables go in classes, but
I’ve seen them in methods too. How does that work? Well, almost anywhere,
inside any box, so long as that box or the box that that box is in, is within a
class box, you can define a variable. Now where you can use that variable is
defined by the box it is in. You cannot access a variable outside the box it is
in. You can, however, access that variable from anywhere inside the same box,
even from a box within that box. So for instance:
{
{
int MyVariable = 10;
{
}
}
}
At the end of this article there is a more info on “Access
Modifiers” and why the above sample isn’t 100% true, but we’ll leave it as it
is for now.
Now then what about methods? Well methods are multiline,
complex statements (blocks). Methods also create a new box, a method box. And
this method box contains a stack of lines of code which are always in the same
order and when you open the box, you go through each line of code in order, doing
what it tells you to do. Now these method boxes are (almost) always contained
within class boxes. So to make a method box you need several things. You need
to know the type of what the final result of going through the box will be. You
need to know what it’s called and you need to know what stuff is required to go
through the lines of code. In real terms these are called the Return type,
Method Name and Arguments. But also since our method is a box, a method box, it
needs curly braces to say where it starts and ends. So here is a full method
box:
void DoNothing(int AnArguement, int AnotherArguement)
{
}
So what does this mean? Well void means the return type (result) is void, empty, nothing. The
type void is type that defines
nothingness. You could also use int but
that would then require the method to return a result of type int. This is done
using the return statement – you’ve come across this before. So this particular
box has return type void, it returns
nothing. It is then called DoNothing and
then we have brackets. Now the brackets (parentheses) just tell the computer
where the list of arguments start and stops. That’s all, nothing more.
Arguments in the list then have a type and a name and are separated by commas.
Very simple, very easy. Arguments just allow you to pass things into the method
box for while it runs the code and new values are passed in for each time it
runs the code. Finally, since this is a box and a box is a complex statement,
we have curly braces but no semi-colon. I think this is now clear.
So what do we have when we see Form1?
Well we have several boxes all inside each other along with
a few variables. Here’s an example:
using System;
using System.Windows.Forms;
namespace HelloWorld
{
class Form1 : Form
{
string MessageString = “Hello world!”;
void Form1()
{
ShowMessage(MessageString);
}
void ShowMessage(string TheMessage)
{
MessageBox.Show(TheMessage);
}
}
}
So what does this all mean?
Well the first two lines are simple code lines and they are
called “using statements”. They say that for the code in this file we will need
to use the code inside the System box and System.Windows.Forms box – don’t
worry that the second name contains the word System. What it means is that
System.Windows.Forms is a namespace box, inside the System namespace box –
don’t worry about the syntax for this, just accept that it is and don’t try
using it for now – you shouldn’t have to at a beginner level.
Then we have namespace
HelloWorld. This tells us we are in the HelloWorld namespace box. It starts
at the first curly brace and the box ends at the corresponding end curly brace,
which is the very last one. Now why is this?
Well just like when you have real boxes within boxes, the
box that is inside cannot spill outside its containing box. So in the same way,
scopes (code boxes) cannot spill outside each other. So when we start a box, it
has to end before its container ends but after all the boxes within it have
ended. So here we can see that the end for the namespace box has to be at the
end of the file.
Now what about this bit? :
class Form1 : Form
{
string MessageString = “Hello world!”;
void Form1()
{
ShowMessage(MessageString);
}
void ShowMessage(string TheMessage)
{
string StartOfMessage = “Message : “;
MessageBox.Show(StartOfMessage + TheMessage);
}
}
Well the word class tells us that we are creating a class
box, and then Form1 gives this class box a name. Now the “ : Form” is tricky.
It tells us that this new type (class box) called Form1 has all the stuff that
is in the Form class box as well. So basically it gives us a load of stuff to
use in our class from the outset. Just remember with this that you can only
ever take stuff from one other box (type) so don’t try something like:
class DummyClass : Form, TextBox
That just wont work…
So we are now inside the class box that creates our form. That
window you see when you run your program? That’s the form. So this class box
contains variables and methods for the form. Remember variables store data; Methods
define a set of instructions for the computer to follow. So our form contains
one variable and two methods. The variable is “MessageString” and the methods
are “void Form1()” and “void ShowMessage(string The Message)”. Now we are going
to forget the “void Form1()” and why it is a unique method, just know that it’s
there and it gets called whenever you create an object of type Form1. Back to
the variable.
The variable is of type string (which is basically text, or
in proper terms, an array of characters). It is called MessageString, and we
assign it the initial value (i.e. we immediately set it to) the value “Hello
world!”. Now since assignment and definition lines are simple lines, there is a
semi colon.
The other method as yet unmentioned is the ShowMessage
method. It has return type void, so it’s not going to have a result, it takes
one argument – TheMessage. TheMessage is of type string and called TheMessage.
The method contains two instructions, two lines of code.
string StartOfMessage = “Message : “;
MessageBox.Show(StartOfMessage + TheMessage);
The first line of code declares and initialises (create and
sets) a variable of type string called StartOfMessage with the value “Message :
“. Note it is a simple line, so has a semi-colon. This variable is within our
method box. So when we leave our method box after finishing all the lines of
code, this variable is lost, destroyed, gone. You can only access it within the
ShowMessage method.
Now the second line of code is also simple line of code so
it has a semi-colon at the end. What it
does is pop up a message box that displays the value of StartOfMessage plus the
value of (the data stored by) the variable TheMessage (the argument). So you
see how data (variables) passed into the method can be used. But note that
variables themselves don’t do anything of their own accord, you have write
lines of code to manipulate them,
i.e. do stuff with them.
So finally, our Form1() method calls the ShowMessage method
passing in the value of MessageString as the argument value for TheMessage. In
other words this is:
When the Form1() box is opened, it opens the ShowMessage box
and puts in the value of MessageString (Hello world!) and calls it TheMessage.
The ShowMessage box method then does as was described.
So the final thing to say is what other types of complex,
multiline boxes there are. Well the next most common has to be the “if” block
(box). The “if” box is a cross between a method and just a simple box. The
syntax is:
if (condition)
{
}
The if box contains lines of code and is a multi-line thing so
uses curly braces and does not need a semi-colon. However, it is also like
calling a method. It needs one argument and that is the condition. Now to pass in this “argument” (though this is not the
real name for it), we have to use the brackets, just as we would for a method.
And the if “method” has one argument of type bool – (a bool is true or false
value; a 1 or 0, a yes or no). So an example if box may be:
if(ShouldShowMessage == true)
{
ShowMessage(“A message”);
}
You see how the if box contains a simple line of code that
has a semi-colon but the if box itself is multiline so doesn’t have a
semi-colon.
But what about when I see this:
if(condition)
else
Why are there no curly braces? Well this is a very special
case and it’s pretty unique to the if, else and else if code. To make code more
compact, the curly braces can be omitted and then the box becomes just one line
long – the //Some line of code. So in
other words if the curly braces are omitted, our box is assumed to be one line
in size.
So a final few things:
You have the else if or else blocks/boxes/scopes which are
done after an if block – the syntax is similar and you’ve probably seen them before.
If not, take a look at the syntax here and you’ll see the similarities. http://msdn.microsoft.com/en-us/library/5011f09h.aspx
The last thing is that scopes can be defined in code when you
feel like it just by using curly braces. You can create boxes that have no type
at all, just by putting curly braces round stuff. E.g. I could do:
{
if(ShouldShowMessage)
{
{
ShowMessage(”A message”);
}
}
}
Which has two extra scopes (boxes) – one round the whole if
block and one inside the if box round the ShowMessage line. Again these are
boxes so don’t need semi-colons. However, they are fairly pointless and don’t
add anything in this case.
You’ll notice I never mentioned those words you may have
seen, Public and Private. These keywords are called Access Modifiers because
the modify (change) what access things have. By default everything inside a box
(scope) is hidden, everything is private. This means stuff outside the box
can’t see it. If you make stuff inside the box public, stuff outside the box
can see that stuff and can start to do things with it. Note: Public and private
only work on 1) class boxes and 2) method boxes or variables that are within a
class box. It does not work within a
method box. I recommend you leave everything as private unless it has to be
public – it’s safer that way J Just as a point, when you do MyObject.MyPublicVariable – the
dot is like pulling out a drawer from
the MyObject box that contains all the public stuff for you to see and then you
picking out the MyPublicVariable.
I hope this now explains far better the workings and ways of
scopes (boxes) and the use of semi-colon and curly braces. Remember, when I use
the word box to mean a programming box in this article, you could equally put
in the proper word scope.
History
20/5/12 - Article first published.