Programming C, C++, Java, PHP, Ruby, Turing, VB
Computer Science Canada 
Programming C, C++, Java, PHP, Ruby, Turing, VB  

Username:   Password: 
 RegisterRegister   
 [WIP] C# Whirlwind
Index -> General Programming
View previous topic Printable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic
Author Message
rdrake




PostPosted: Fri May 11, 2007 6:58 pm   Post subject: [WIP] C# Whirlwind

C# Whirlwind

What is C# and The .NET Framework?
C#, pronouced "C Sharp," is a language designed by Microsoft and certified by the EMCA. It is a major language in the .NET Framework and one of the most widely used. It has many simiarities to the Java language syntax-wise.

The .NET Framework, pronounced "Dot Net," is a large collection of class libraries written by Microsoft to rapidly create applications. The Framework includes many powerful libraries, making it much easier to develop on. The .NET vision was first outlined by Bill Gates in 2001, with release 1.0 occurring not too much later. The upcoming version of .NET is 3.0 and it promises even more enhancements and large changes.

C# combined with the .NET Framework is a powerful combination. Applications can be built quickly and easily, with a large developer community backing both technologies.Similarly to Java, C# requires a runtime environment be installed. When users wish to run your application they will need the .NET runtime package to be installed.

How Can I Get .NET and C#?
If you are running Microsoft Windows, chances are you have the .NET Framework installed already. If not, version 2.0 is the current version and it is available from the Microsoft download site

here. The SDK includes many useful tools for debugging your applications, it also includes a compiler which we need to compile our applications. I still recommend version 2.0 as it is known to be stable, and since 3.0 has not been fully deployed yet.

Not on Windows? Novell sponsors a wonderful cross platform implementation of the .NET framework complete with a C# compiler and all. Its name is Mono, and it can be found here. Please note while nearly complete, it still is not 100% complete. Some major components (Windows Forms being a big one) are still not fully implemented. For the time being we need not worry about the omissions.

Basic Data Types
C# has all your basic data types like integers, booleans, strings, and many more. You can even declare your own types with custom classes. Variable declaration is also very similar to many other C-like languages.

code:
int myNumber = 42;
string myName = "rdrake";
bool myBool = true;


Hello, World!
An example C# program would be the following hello world example:

code:

using System;

class HelloWorld
{
    public static void Main()
    {
        Console.WriteLine("Hello, World!");
    }
}

Just for comparison the following is an equivalent Java version:
Java:
public class HelloWorld
{
   public static void main(String[] args)
   {
      System.out.println("Hello world!");
   }
}


You compile the C# example with the following line:
code:
csc.exe helloworld.cs

Alternatively using Mono:
code:
mcs.exe helloworld.cs


How Does The Above Work?

code:

using System;
This tells the compiler we wish to use the "System" class library. The majority of programs will use this above line, though it is not necessary as I will later demonstrate.

code:

class HelloWorld
{

}
This is our class. C# is Object Oriented and therefore we must wrap everything inside of classes. This makes our code much more manageable.

code:

    public static void Main()
    {

    }
This is our method. It is named "Main" as that name dictates to the C# compiler that that particular method is our entry point (ie. where the compiler goes to first). Notice how it is marked as "static." This does not really matter to us now, but it will in the future. It must always be marked as static. Also note its return type is void, which of course means it returns nothing.

code:

        Console.WriteLine("Hello, World!");
Lastly we actually output something. In this case we are using the "WriteLine" method from the "Console" class which belongs to the "System" namespace. Remember how I said we have "using System;" in nearly every program, but we don't always have to have it? That's because the above can be rewritten as the following:

code:
class HelloWorld
{
    public static void Main()
    {
        System.Console.WriteLine("Hello, World!");
    }
}
By using the using keyword we save ourselves from typing so much.

More Methods
Ok so enough of our single example, let's write more complicated programs. Classes you write can have as many methods in them as you'd like. Typically your Main() method won't do everything the class needs to do. In fact, you only ever need one Main() method in your entire application.

Let's revisit our Hello World example:
code:
using System;

class HelloWorld
{
    public static void Main()
    {
        SayHello();
    }

    private static void SayHello()
    {
        Console.WriteLine("Hello, World!");
    }
}
Notice how there is a difference in how I declare the SayHello() method compared to the Main() method. I have marked SayHello() as private. Why? It is a helper method. It is only ever called by methods inside the class, and therefore can be marked as private. Also notice it is marked as static as well. This is because it is called without an instance of the HelloWorld class being created. More on this later.

A Little I/O
You've already seen output, but what about input? Input is achieved via many ways, the easiest of which is the "ReadLine()" method. It reads in a line and assigns the value to a string.
code:
using System;

class MainClass
{
    public static void Main()
    {
        string name;

        Console.WriteLine("Please enter in your name:");
        name = Console.ReadLine();
        Console.WriteLine("Welcome, {0}!", name);
    }
}


Ok, Enough With Hello World
Let's create a class representing a real world object, a Dog.

code:
using System;

// This class exists souly to create an instance of another class.
class MainClass
{
    // Our main entry point into the program.
    public static void Main()
    {
        // Create a new instance of the 'Dog' class named 'spike'.
        Dog spike = new Dog();
        spike.RollOver();
        spike.MakeNoise();
    }
}

// A class representing a dog.
class Dog
{
    // A trick many dogs can perform.
    public void RollOver()
    {
        Console.WriteLine("I rolled over.");
    }

    // Any dog we want to represent barks.
    public void MakeNoise()
    {
        Console.WriteLine("Bark!");
    }
}
There are a few new items to be seen in the above example, but many are the same as before. Notice how in the Dog class nothing is marked static. In our MainClass class we create an instance of the Dog class named spike. We then call methods from the Dog class on the spike instance. Since we created an instance of the Dog class, the Dog class need not have static methods.

Inheritance, A Programmer's Best Friend
Sometimes you will come across situations where a collection of objects share similar properties, but vary in some way. Going back to our dog example, some dogs yip while other dogs bark... and some dogs even howl.

code:
using System;

class MainClass
{
    // Our main entry point into the program.
    public static void Main()
    {
        // Create a new instance of the 'Dog' class named 'spike'.
        Console.WriteLine("Spike:");

        Dog spike = new Dog();
        spike.RollOver();
        spike.MakeNoise();

        // Create an instance of the Beagle class named Rufus.
        Console.WriteLine("Rufus:");

        Beagle rufus = new Beagle();
        rufus.RollOver();
        rufus.MakeNoise();
    }
}

// Our Dog class.
class Dog
{
    public void RollOver()
    {
        Console.WriteLine("I rolled over.");
    }

    // Notice how we marked this method as virtual.
    public virtual void MakeNoise()
    {
        Console.WriteLine("Bark!");
    }
}

// Beagle inherits all the methods from Dog.
class Beagle : Dog
{
    // Here we over ride the MakeNoise method.
    public override void MakeNoise()
    {
        Console.WriteLine("Howl!");
    }
}
Let's compile and run it. Taking a look at the output, we see the following:
code:
Spike:
I rolled over.
Bark!
Rufus:
I rolled over.
Howl!
So what the hell is going on here? Well, the Beagle class is inheriting all the methods from the Dog class. Sometimes one might wish to override the behaviour of one of the methods. Such a task is accomplished by declaring "virtual methods" in the base class. Virtual methods are methods which stand in should no replacement methods be specified in the derived classes.

In the Beagle class we override this method by using the "override" keyword. Please note, the method signature (ie. output type, name, and accessibility modifier) must match that of the overridden class.

This behaviour is exploited quite often by developers writing their own classes. There are many cases where one would want to override the "ToString()" method in their own classes.

Properties
There are many instances where we might wish to store certain values in an object. Such values are typically stored as properties of the object. For example, we may wish to store things like the fur colour and name of the dog in the class.

code:
using System;

class MainClass
{
    // Our main entry point into the program.
    public static void Main()
    {
        // Create a new instance of the 'Dog' class named 'spike'.
        Console.WriteLine("Spike:");

        Dog spike = new Dog();
        spike.GivenName = "Spike";
        spike.RollOver();
        spike.MakeNoise();
        spike.FurColour = "Brown";
        spike.Colour();

        // Create an instance of the Beagle class named Rufus.
        Console.WriteLine("Rufus:");

        Beagle rufus = new Beagle();
        rufus.GivenName = "Rufus";
        rufus.RollOver();
        rufus.MakeNoise();
        rufus.FurColour = "Black";
        rufus.Colour();
    }
}

// Our Dog class.
class Dog
{
    // Variables which hold properties are usually declared private as we want to
    // restrict access to them.
    private string _GivenName;
    private string _FurColour;

    // Notice how the next two blocks differ from regular methods.  They are called
    // setters/getters, and restrict access to our properties.  In this way, we can
    // make certain properties read-only, make sure they are valid, and much more.
    public string GivenName
    {
        get { return _GivenName; }
        set { _GivenName = value; }
    }

    public string FurColour
    {
        get { return _FurColour; }
        set { _FurColour = value; }
    }

    public void RollOver()
    {
        Console.WriteLine("{0} rolled over.", _GivenName);
    }

    public void Colour()
    {
        Console.WriteLine("The fur colour of {0} is {1}.", _GivenName, _FurColour);
    }

    // Notice how we marked this method as virtual.
    public virtual void MakeNoise()
    {
        Console.WriteLine("Bark!");
    }
}

// Beagle inherits all the methods from Dog.
class Beagle : Dog
{
    // Here we over ride the MakeNoise method.
    public override void MakeNoise()
    {
        Console.WriteLine("Howl!");
    }
}
You should note that properties are kept private, with access kept restricted through the use of what are called "setters" and "getters". This allows us finer control over what values get assigned to the properties. This is useful for something like an age property, where you want an age that is greater than zero.

Partying With Polymorphism
You may run into situations where you need a method with a certain name to do many things. Let's say you want to modify the Dog and Beagle classes so instead of specifying the name and fur colour after the fact, you can specify them when creating the instance of the class. The problem is you want to keep it the way it was before too, so the user can enter in the name of the dog and the fur colour later on if they wish. This is simple enough to accomplish via polymorphism.

code:
using System;

class MainClass
{
    // Our main entry point into the program.
    public static void Main()
    {
        // Create a new instance of the 'Dog' class named 'spike'.
        Console.WriteLine("Spike:");

        // Instead of specifying the properties later, let's do it upon construction
        // of the class.
        Dog spike = new Dog("Spike", "Brown");
        spike.RollOver();
        spike.MakeNoise();
        spike.Colour();

        // Create an instance of the Beagle class named Rufus.
        Console.WriteLine("Rufus:");

        Beagle rufus = new Beagle();
        rufus.GivenName = "Rufus";
        rufus.RollOver();
        rufus.MakeNoise();
        rufus.FurColour = "Black";
        rufus.Colour();
    }
}

// Our Dog class.
class Dog
{

    // Variables which hold properties are usually declared private as we want to
    // restrict access to them.
    private string _GivenName;
    private string _FurColour;

    // Notice how the next two blocks differ from regular methods.  They are called
    // setters/getters, and restrict access to our properties.  In this way, we can
    // make certain properties read-only, make sure they are valid, and much more.
    public string GivenName
    {
        get { return _GivenName; }
        set { _GivenName = value; }
    }

    public string FurColour
    {
        get { return _FurColour; }
        set { _FurColour = value; }
    }

    // We still need our old constructor for the Beagle class
    public Dog()
    {

    }

    // Our special new constructor.
    public Dog(string givenName, string furColour)
    {
        _GivenName = givenName;
        _FurColour = furColour;
    }

    public void RollOver()
    {
        Console.WriteLine("{0} rolled over.", _GivenName);
    }

    public void Colour()
    {
        Console.WriteLine("The fur colour of {0} is {1}.", _GivenName, _FurColour);
    }

    // Notice how we marked this method as virtual.
    public virtual void MakeNoise()
    {
        Console.WriteLine("Bark!");
    }
}

// Beagle inherits all the methods from Dog.
class Beagle : Dog
{
    // Here we over ride the MakeNoise method.
    public override void MakeNoise()
    {
        Console.WriteLine("Howl!");
    }
}


A Little With Control Flow
Let's take a break from talking about methods and classes and talk about control flow. Control flow in C# is generally the same as in C-like languages. I'll just demonstrate an example of each of the major ones.

If Statement
code:
int numberOfDogs = 4;

if (numberOfDogs < 0)
{
    Console.WriteLine("Impossible!");
}
else if (numberOfDogs < 10)
{
    Console.WriteLine("Sounds more reasonable to me.");
}
else
{
    Console.WriteLine("Too many dogs, I don't believe you.");
}


Switch
There are cases where if statements would be too repetative. In this case, we use a switch.
code:

string dogName = "Rover";

switch(dogName)
{
    case "Spike":
        Console.WriteLine("Sounds like a big dog.");
        break;
    case "Fido":
    case "Rufus":
        Console.WriteLine("Sounds like a small dog.");
        break;
    default:
        Console.WriteLine("Really not sure what kind of dog that is.");
        break;
}


While and Do While Loops
An example of a while loop:
code:
while(condition)
{
    // Execute some code.
}


An example of a do while loop:
code:
do
{
    // Execute some code.
} while(condition);

You would use a do while loop instead of a normal while loop in cases where you wish for the code block to execute at least once before termination.

For and Foreach
For loop:
code:
for (int i = 0; i < 10; i++)
{
    Console.WriteLine(i);
}


Foreach loop:
code:
foreach (Dog dog in dogs)
{
    // Produce a listing of dog names.
    Console.WriteLine(dog.Name);
}


Generic Collections, Another One of Man's Best Friends
I'm sure many of us have heard of arrays, problem is they have a fixed length and take time to copy over in order to expand or shrink. The solution? Collections. Collections can store virtually any type of data in them and are great for passing around groups of objects.

Let's create a demonstration of a collection:
code:
using System;

class MainClass
{
    public static void Main()
    {
        ArrayList dogs = new ArrayList();
       
        Dog fido = new Dog("Fido", "White");
        Dog spike = new Dog("Spike", "Brown");

        dogs.Add(fido);
        dogs.Add(spike);
        dogs.Add(42);
    }
}
Now, you may be wondering "Why in the hell are you adding an integer into that collection?" The answer is simply because I can, regular collections are not type safe. That is to say, you can add pretty much any object to them. This normally isn't an issue, except that you may wish to iterate through said collection and try to access a property of each object in the class. Some objects in the collection may not support that property and cause an exception.

We solve this by using generic classes, which are type safe:

code:
using System;

class MainClass
{
    public static void Main()
    {
        List<Dog> dogs = new List<Dog>();
       
        Dog fido = new Dog("Fido", "White");
        Dog spike = new Dog("Spike", "Brown");

        dogs.Add(fido);
        dogs.Add(spike);
    }
}
This only allows us to add "Dog" objects to the collection, meaning any operations that work on one object in the class should work on all the objects in the class. This is a very handy thing.

A Note About Style
If you were paying attention to the above code snippets, you would have noticed a certain style. Things like language keywords are always written in lower case. Writing in upper case will lead to syntax errors. Variables always follow camlCase, with the exception of properties which follow PascalCase.

Method names and class names are always written in PascalCase as well. Properties of a class are _WrittenLikeThis, with an underscore before its name. Also note the braces begin on the next line. The only case where I do not follow this is when declaring setters/getters.

Comments should be full sentences whenever possible written on the line above the line or block it is a comment for. Comments are written inline with the code they refer to and never appear beside a line of code.

Further Reading and Conclusion
There are a number of great resources out there:


Well, I hope this was somewhat informative and enjoyable. It's my first Whirlwind and I haven't proofread it yet, so if you find any mistakes, please contact me and I'll correct them. If there's a concept I did not explain enough of, please let me know as well. C# is a large language and it is difficult to cover everything, if you wish to have something covered, contact me Smile.
Sponsor
Sponsor
Sponsor
sponsor
haskell




PostPosted: Fri May 11, 2007 10:25 pm   Post subject: RE:[WIP] C# Wirlwind

There are many open-source implementations of the .NET framework besides Mono. DotGNU is one of them.

SharpDevelop is a very good open-source IDE for C#/VB.NET. It has many of the same features as Visual Studio, with many possible add-ons so you can get your desired environment.
rdrake




PostPosted: Sat May 12, 2007 1:37 am   Post subject: Re: [WIP] C# Wirlwind

A quick correction to one of the sections above. When using collections and generic collections, we must include the proper using statement. Unfortunately I cannot edit my own post, so I'll show how it should have looked here.

Generic Collections, Another One of Man's Best Friends
I'm sure many of us have heard of arrays, problem is they have a fixed length and take time to copy over in order to expand or shrink. The solution? Collections. Collections can store virtually any type of data in them and are great for passing around groups of objects.

Let's create a demonstration of a collection:
code:
using System;
using System.Collections;

class MainClass
{
    public static void Main()
    {
        ArrayList dogs = new ArrayList();
       
        Dog fido = new Dog("Fido", "White");
        Dog spike = new Dog("Spike", "Brown");

        dogs.Add(fido);
        dogs.Add(spike);
        dogs.Add(42);
    }
}
Now, you may be wondering "Why in the hell are you adding an integer into that collection?" The answer is simply because I can, regular collections are not type safe. That is to say, you can add pretty much any object to them. This normally isn't an issue, except that you may wish to iterate through said collection and try to access a property of each object in the class. Some objects in the collection may not support that property and cause an exception.

We solve this by using generic classes, which are type safe:

code:
using System;
using System.Collections.Generic;

class MainClass
{
    public static void Main()
    {
        List<Dog> dogs = new List<Dog>();
       
        Dog fido = new Dog("Fido", "White");
        Dog spike = new Dog("Spike", "Brown");

        dogs.Add(fido);
        dogs.Add(spike);
    }
}
This only allows us to add "Dog" objects to the collection, meaning any operations that work on one object in the class should work on all the objects in the class. This is a very handy thing.

Figures the only code I don't test is the code that is not correct...
wtd




PostPosted: Sat May 12, 2007 1:48 am   Post subject: RE:[WIP] C# Wirlwind

Good start.
wtd




PostPosted: Sun May 13, 2007 4:38 pm   Post subject: RE:[WIP] C# Whirlwind

Delegates!
rdrake




PostPosted: Sun May 13, 2007 9:51 pm   Post subject: Re: [WIP] C# Whirlwind

Looking to the Future: C# 3.0
Slated for inclusion in version 3.5 of the .NET Framework, C# 3.0 promises a number of helpful features many of us find in various languages, but miss in C# 2.0. There are a number of changes, but I will only cover a few for now.

Implicitly Typed Local Variables
Yes, this we have taken advantage in languages like Ruby for a long time now, and they've finally made it to C#. Let's take a look at some old 2.0 code, then its 3.0 replacement.

code:
int i = 5;
System.Console.WriteLine(i);
Fairly straight forward, now here's the 3.0 version:
code:
var i = 5;
System.Console.WriteLine(i);
Doesn't seem like much, but it appears more helpful in other situations.

Object Initializers
I'm sure anybody here whose written C# or Java classes realizes that properties and class constructors are all basically redundant code. Well, you have more options now thanks to object initializers and a new short hand for getters and setters (ie. public methods that control access to properties in a class).

Consider an updated version of my favourite above code example:

code:
using System;

class MainClass
{
   public static void Main()
   {
      Console.WriteLine("Spike:");

      var spike = new Dog {GivenName = "Spike", FurColour = "Brown"};
      spike.RollOver();
      spike.MakeNoise();
      spike.Colour();

      Console.WriteLine("Rufus:");

      var rufus = new Beagle {GivenName = "Rufus", FurColour = "Black"};
      rufus.RollOver();
      rufus.MakeNoise();
      rufus.Colour();
   }
}

class Dog
{
   public string GivenName { get; set; }
   public string FurColour { get; set; }
     
   public virtual void RollOver()
   {
      Console.WriteLine("{0} rolled over.", GivenName);
   }
   
   public virtual void MakeNoise()
   {
      Console.WriteLine("Bark!");
   }
   
   public virtual void Colour()
   {
      Console.WriteLine("The fur colour of {0} is {1}.", GivenName, FurColour);
   }
}

class Beagle : Dog
{
   public override void MakeNoise()
   {
      Console.WriteLine("Howl!");
   }
}
Notice how there are no longer constructors, and the syntax for creating a new Dog object has changed slightly. Also note the changes to the properties. Much nicer, wouldn't you say? It allows us to still have fine grained control over properties when we need to, but also saves us from writing so much redundant code.
rdrake




PostPosted: Sun Jul 22, 2007 12:23 am   Post subject: Re: [WIP] C# Whirlwind

Since learning about conventions in a particular language helps you understand previously written code, and can also help you write more understandable code for when you need help, I've decided to go over some of the basics one should know.

Let's start off with an example:
code:
using System;

class HelloWorld
{
    public static void Main()
    {
        Console.WriteLine("Hello, World!");
    }
}
Not much, is it? Notice how the class name is in Pascal case and only contains nouns, the brackets are in Allman style, method names are also Pascal case with no space between the name of the method and the parenthesis. The latter is also true with calls to methods. Generally most code is indented with 4 spaces (though this is optional and can easily be changed).

Ok, let's go back to one of the examples I wrote earlier, only in a smaller form:
code:
using System;

class Dog
{
    // Variables which hold properties are usually declared private as we want to
    // restrict access to them.
    private string _GivenName;

    public string GivenName
    {
        get { return _GivenName; }
        set { _GivenName = value; }
    }

    public void Colour()
    {
        Console.WriteLine("The fur colour of {0} is {1}.", _GivenName, _FurColour);
    }

    // Notice how we marked this method as virtual.
    public virtual void MakeNoise()
    {
        Console.WriteLine("Bark!");
    }
}
Again with the class name being a noun and the lack of spaces between the parenthesis and the name. Also notice how the member variable is written prefixed with an underscore and in Pascal case. This is one of the few places where there are a few different conventions. Some people would rewrite the "_GivenName" as "_givenName." Another convention that is generally not used so much anymore would be to write it as "m_givenName" for member variable." Generally member variables are marked as private and only made available through getters and setters.

Some more:
code:
for (int i = 0; i < 5; i++)
{
    Console.WriteLine(i);
}
Notice the space between the keyword and the first parenthesis, this is generally how most statements and expessions are written. It is considered acceptable to use a short identifier for short loops like a for loop, but bad for things like a foreach loop. Declaration of the identifier usually occurs there as well. Now, some of you may know that braces in this case are optional. However, it generally is considered bad practice to omit these braces.

code:
private int SquareTheValue(int valueToSquare)
{
    return valueToSquare * valueToSquare;
}
Parameters are written in camel case and return statements do not have parenthesis wrapped around them.

code:
int value;
value = 42;
Never ever do this. Really, don't do this in any other language. Unless there is a real good reason, always do it this way:
code:
int value = 42;
Always initialize a variable after declaration where at all possible.

code:
private double MultiplyByPI(double value)
{
    return value * 3.14159;
}
Magic number? Evil! Always declare a would be magic number as a constant then use that.
code:
private const double PI = 3.14159;

private double MultipleByPI(double value)
{
    return value * PI;
}
Much better, don't you think?

Something else you may have noticed, "PI" is written in all caps. Generally anything from 1-2 letters may remain all caps, anything longer is written in (you guessed it) Pascal case. You can notice this in the .NET BCL naming conventions.

code:
using System.IO;
using System.Xml;


Typically you use block comments (/* */) to document your source files in some languages. You should always use the following way for C#:
code:
/// <summary>
/// This is a really neat method that does some various things.  You
/// should all be jealous of this method and how great it is.  Rambling
/// on and on and on and on and on is fun.
/// </summary>
/// <returns>The answer to life, the universe, and everything.</returns>
public int GetTheAnswer()
{
    return 42;
}
This is better documented here.

Multiple member variables are usually declared on their own line:
code:
private int _A;
private int _B;
private int _C;
This way you can easily document each variable.

Well, I'm sure a missed a few conventions but those are some of the main ones that are generally used. Do you have to agree with these conventions? No. However, this is generally what I see and write when it comes to C#.

My apologies to those who had to suffer through my disorganization of this.
Display posts from previous:   
   Index -> General Programming
View previous topic Tell A FriendPrintable versionDownload TopicSubscribe to this topicPrivate MessagesRefresh page View next topic

Page 1 of 1  [ 7 Posts ]
Jump to:   


Style:  
Search: