Week 1 OverviewBefore I begin, let me tell you a bit about why I decided to use the C# Specification for the C# Workshop, some of the observed problems we're having so far, and how I plan to solve those problems.
First, I decided to use the C# Specification as the official documentation for the C# Workshop because it was both free, complete, and designed for intermediate to advanced programmers. You see, during the C++ Workshop we used a very rudimentary text designed for the complete beginner, and we also moved very slowly. The end result was that people got bored of the workshop, and eventually decided to quit. I wanted to avoid repeating a similar mistake, so instead I created a brand new one. In an attempt to accelerate the workshop to make it more interesting, and to make sure we were all able to use a freely available text, I chose the C# Specification. Unfortunately, I did so without considering how the participants of the C# workshop might be different from those of the C++ Workshop.
First, there's been a much larger interest in the C# Workshop than the C++ Workshop. This has guaranteed it's exposure to a larger audience of people. As well, unlike with C++ where many people were already experienced programmers, there's probably only a dozen or so very experienced C# programmers here on GDNet actively participating in the workshop (out of roughly 400 participants). And finally, C#, unlike C++ is advertised as a very user-friendly and easy to learn language. This has caused far more beginning programmers to join the C# workshop than joined the C++ workshop. What's the end result? The end result is that the C# specification isn't suitable as a beginning learning device, and consequently, not the best suited text for this workshop's audience.
Ok, so we're now working with a text which, although is a good, complete resource - may not be the best resource for the workshop. How do we fix it? Simple. With supplementary text. In specific, I will speak to those people who've volunteered as tutors and either myself or one of them will write an overview for each weekly thread which contains a more tutorial style introduction to the material. The overviews will not go into nearly as much depth as that covered in the specification, but it will provide more examples and it will present some of the most important information in a more human-readable format. I will be writing a partial overview below to give people an idea of what these overviews might be like. Please provide your feedback. If there's not enough interest or usefulness in writing such an overview for each weekly thread, please say so, as it's a time-consuming endeavor on top of an already time-consuming endeavor, and we dont want to burden either myself or the other tutors needlessly if the information and style presented here isn't useful to those beginning C#.
The text assigned to week 1 is chapters 1 and 2. The first chapter serves as an overview of the entire language, giving you just enough information to make you familiar with the terms and concepts of the C# language. Unfortunately, they dont give a slew of examples, nor do they frequently explain the how or the why of something. I dont want to make chapter 1 responsible for scaring people off, suggesting they need to learn the entire language within the first week, however people have already begun reading and are now becoming overwhelmed. At this point, the cat is out of the bag. The only way to move forward as I can see it, is to explain each of those topics a bit further, so they at least make enough sense that people can move forward without feeling like they were left in a deserted field and cluster-f&*!#d. But again, keep in mind that we will go into each topic in more details, one at a time, in the coming weeks. For now, you should just be familiar with the terminology and basic syntax presented here. Ok, let's get it started...
Hello WorldIt's customary when demonstrating a new language to use the "Hello World" example. Since I'm a fan of tradition, I'll do the same. I'll present the code first, and then explain it in more detail afterwards.
1: class HelloWorldProgram2: {3: static void Main()4: {5: System.Console.WriteLine("Hello World");6: }7: }
The above is a very simple example of a completely functional C# application. When compiled it create an executable assembly which, when executed, outputs "Hello World" (without quotes) to the console window. You should enter the above, without the line numbers, into your C# compiler, build and execute the above to see it in action.
Line 1 of the source code is what is called a class declaration. In C# all data and operations exist within a class, and there must be at least 1 class in any C# application. "But what is a class?" For now, just know that a class is a container for all data and operations within an application or library. We'll get into more detail about what a class is and how it's used in a few moments.
Lines 2 and 7 indicate the extents of the class declaration. Everything between the open '{' and close '}' brackets are considered part of the class. All functions, fields, events, delegates, etc...contained between the { and } are called Members of the class.
In this case, we've created a class called "HelloWorldProgram", and we've given it a single method (aka member function) called "Main". On line 3 you can see the declaration for the method called main. You'll also notice that there are two other words in that line - static and void.
Static is a keyword, which in this context, is used to indicate that the method Main is part of HelloWorldProgram, as a class, and does not require an instance of HelloWorldProgram as an Object. The difference between classes and objects will be explained later. For now, just recognize that all C# console programs must have a method called Main, and it must be declared static.
The second thing you'll see on that line is the type name "void". Void is actually a type used to indicate no type at all. Normally, a type name preceding a method name indicates what kind of value is returned from a method. When void is specified, it means the method doesn't return a value. In C#, the return value for main can either be 'int' or 'void'. If int is specified the programmer is responsible for returning a value. If void is specified, the programmer CANNOT return a value, and the value 0 is returned automagically.
On line 5 you see the real meat of the application. Up until this point, everything we've seen so far will exist in every C# console application you ever make. In fact, you could take out line 5, and just save everything else as a template application if you wanted to. (Note, you dont have to, Visual C# 2005 EE does that for you. Whenever you create a new console application, the class and Main are provided for you). On line 5 we have the line:
System.Console.WriteLine("Hello World");
The above code may at first appear confusing, but when we break it down into sections, it makes much more sense. The first part is "System". Whenever a programmer writes instructions for a computer, they do so using variables which they create. These variables all have types, and every type has a name called its...wait for it...type name. To make sure the name of their types do not collide with other peoples types, they are grouped into namespaces. Think of it this way...lets say my name is Adam. At my university there may have been hundreds of Adams. How would someone know who I am by name from someone else with the same name? Simple, by also using my last name. If you were to say "Adam Smith", then people would immediately know you didn't mean "Adam Johnson". In other words, the last name of the individual helps to qualify WHICH individual is being referred to. Namespaces are the exact same thing. By grouping types into namespaces, we are in essence giving them a last name. And whenever there is confusion about which type to use with a similar name, a programmer can fully qualify it by identifying the namespace.
In the example above, we are wanting to reference the 'Console' class. But in order to do so I must instruct the compiler WHICH console I want to use. In this case, I have fully qualified which Console I want to use by also including its namespace, ie. System. There are alternative ways to indicate which namespace a type belongs to, but for the sake of this introduction I'll leave it at that.
The next part of the instruction above is "WriteLine". An identifier followed by ( followed by some optional information followed by ) is what's referred to as a method in C#. Using a method in that format invokes that method, causing it to execute code. In this case I'm invoking the WriteLine method of the Console class, in the System namespace. I'm also passing the method the parameter "Hello World". This, in whole, prints whatever I pass into WriteLine out to the console window.
Types & VariablesNow that we've taken a look at a basic C# application, lets make it a little more interesting. Lets start by adding some variables using the simple types that the C# language understands.
1: class CharacterNameProgram2: {3: static void Main()4: {5: Character myCharacter = new Character();6: myCharacter.name = "Jeromy Walsh";7: 8: System.Console.WriteLine(myCharacter.name);9: }10: }11: 12: class Character13: {14: public System.String name;14: }
In the above example I've created a new class type called Character beginning on line 12. Character has one Field (variable) which is called name. Name is of type String. This is how you'd declare a publicly accessible field in C#. On line 5 of the Main method I create a new instance of myCharacter. On line 6 I assign the value "Jeromy Walsh" to my character's name. On line 8 I print the name of my character out to the console.
The above is just something to demonstrate how someone might use one of the simple data types. Among the other simple data types are int, byte, char, float, bool, and decimal. There are also enums and structs, but we'll talk more about that later. Lets expand the above to include some additional fields, which describe my Character class.
1: class CharacterInfoProgram2: {3: static void Main()4: {5: Character myCharacter = new Character();6: myCharacter.name = "Jeromy Walsh";7: myCharacter.age = 27; 8: myCharacter.weight = 165;9: myCharacter.middleInitial = 'L';10: 11: System.Console.WriteLine(myCharacter.name);12: }13: }14: 15: class Character16: {17: public System.String name;18: public byte age;19: public int weight;20: public char middleInitial;21: }
Each of the above fields use a different simple type, and each one accepts different types of values with different ranges. There is a complete table in your text which shows what types of data can go in each type, and what the possible ranges of values are.
ExpressionsThe next section of this overview deals with expressions. As indicated in your text, an expression can really be anything that returns a value, including allocation of new objects, comparisons, or even method invocations. But the thing people think of most when talking about expressions are mathematical expressions. That is, statements in the form 'x = m * a + b'. So I've created a quick example showing a practical set of expressions.
1: class CharacterFightProgram2: {3: static void Main()4: {5: Character rand = new Character();6: rand.Name = "Rand";7: rand.Level = 5;8: rand.HitPoints = 50;9: rand.Strength = 5;10: rand.Armor = 5;11: 12: Character Semirhage = new Character();13: Semirhage.Name = "Semirhage";14: Semirhage.Level = 4;15: Semirhage.HitPoints = 40;16: Semirhage.Strength = 4;17: Semirhage.Armor = 4;18: 19: rand.Attack(Semirhage);20: System.Console.WriteLine("{0}'s hitpoint are now {1}.", Semirhage.Name, Semirhage.HitPoints);21: }22: }23: 24: class Character25: {26: public void Attack(Character enemy)27: {28: int damage = 0;29: damage = Level + Strength;30: 31: int resistance = 0;32: resistance = enemy.Level + enemy.Armor;33: 34: int totalDamage = damage - resistance;35: 36: if (totalDamage <= 0) 37: totalDamage = 1;38: 39: enemy.HitPoints -= totalDamage;40: }41: 42: public int HitPoints43: {44: get { return m_Hitpoints; }45: set46: {47: if (value < 0) m_Hitpoints = 0;48: else m_Hitpoints = value;49 }50: }51: 52: public System.String Name; 53: public int Level;54: public int Strength;55: public int Armor;56: 57: private int m_Hitpoints;58: }
In the program above, you can see several expressions. First, lines 6-10 and again on lines 13-17 we are creating expression statements which assign values to the public fields of type "Character". On line 19 there is method invocation expression which returns void. And finally,
the majority of expressions are happening between lines 28 and 39. Let me explain these lines in a bit more details.
Lines 28, 31, and 34 are not expressions, they are technically local variable declarations, as we're allocating memory and declaring variables via an identifier which will be used throughout the rest of the method.
Line 29 is an expression which computes this character (rand's) damage output, based on a formula of his strength plus his level.
Line 32 is an expression which computes the enemies resistance, based on his level and his armor.
Line 34 is an expression where we compute the total damage done, by subtracting the resistance from the damage possible.
Line 36 is actually an if-statement, however the if-statement contains a boolean expression "totalDamage <= 0" which returns either true or false depending on the value of totalDamage. In the example, it returns false.
And finally, line 39 is an expression which uses the -= operator. This operator can be expanded into the form:
enemy.HitPoints = enemy.HitPoints - totalDamage;
You can now see the expression simply subtracts the totalDamage from the enemy's hitpoints, and then assigns it back to her hitpoins.
In C#, and especially in game development, the majority of your statements will either be expressions, declarations, or conditionals and branching such as if, else, switch, for, and while.
If you've found the above a more human-readable format for learning beginning C#, please let me know. Note, this is again just an overview of the information in week 1. If this format receives enough interest, myself or another tutor will write similar overviews for the remaining chapters. Also, please let me know if the above is detailed enough, not detailed enough, etc...What do you want more of, what do you want less of?
This workshop is really about all of you. If you're not getting what you want, or what you expected from the workshop, please speak up so we know what level we need to cater to. If there's enough interest in this format, I'll begin by completing the information below.
Arrays // Coming soon...
Structs // Coming soon...
Enums // Coming soon...
Classes & Objects // Coming soon...
Interfaces // Coming soon...
Delegates // Coming soon...
Attributes // Coming soon...