Enums and Switch Blocks

Enumerations in VB.NET and C# are fairly simple, although, in C#, as you may expect, you'll need some sort of punctuation mark to delimit items in the enumeration. This time, it's a comma, though, and not a semicolon.
    public enum Element {
        Hydrogen = 1,
        Helium,
        Lithium,
        Beryllium,
        Boron,
        Carbon,
        Nitrogen,
        Oxygen,
        Fluorine,
        Neon
    } // End of enumeration of elements.
Of course, enumerations are nice substitutes for variables that represent something other than a number. Too many times have I seen people passing descriptive strings around and doing string comparisons when they could do the same thing with just a number or, even better, an enumeration. An example of how you could work with enumerations in C# (there is no difference in enumeration usage between VB.NET and C#).
        private void btn11_Click(object sender, EventArgs e) {
            Element thing;
            thing = Element.Fluorine;
            if (thing == Element.Fluorine) {
                MessageBox.Show("You found Fluorine!");
            } // End of if block for checking fluorine.
        } // End of btn 11's click.
In some projects, you would see a bulky string being passed to do the same thing. Remember that strings are meant to be displayed. If you are not displaying your string, you probably shouldn't be using a string!
Here's a further example of how you might use enumerations. Notice the switch keyword.
        public void AtomicInformation(out int AtomicNumber, out float AtomicWeight, out string ChemSymbol, Element el) {
            AtomicNumber = ( int )el;
            switch (el) {
            case Element.Hydrogen:
                AtomicWeight = 1.00794f;
                ChemSymbol = "H";
                break;
            case Element.Fluorine:
                AtomicWeight = 18.9984032f; // This number is too big to be stored as a float.
                ChemSymbol = "F";
                break;
            case Element.Helium:
                AtomicWeight = 4.002602f;
                ChemSymbol = "He";
                break;
            default:
                AtomicWeight = 0f;
                ChemSymbol = "?";
                break;
            } // End of switch (el)
            return;
        } // End of atomic information function.
As you may suspect, the switch keyword is the equivalent to the Select Case in VB.NET. In C#, the switch statement is a teense more unwieldy than in VB.NET, but let's investigate the usage of switch blocks.
First is the switch statement, which is essentially setup to look like the beginning of most blocks. However, instead of a condition in the parentheses, you can put any quantity in the parentheses (that can be used to equate to other values). The value of the quantity in the parentheses determines which case that execution is transferred to. Execution then goes to the case statement. The break statement is required in C# and there is no equivalent in VB.NET that is necessary in this case. It's essentially a required line that you put to prevent execution of the next block. However, you will get an error if you omit it. The only other valid option to have instead of break is return. Break takes you to the line after the closing brace of the switch block. Return takes you out of the subroutine/function. It's probably not a good idea to try to return from some blocks and break from others in the same switch block, although it is possible. The above block could work with all of the breaks replaced with returns - this would make the return at the end of the switch block unnecessary - but it's much safer to have break statements for switch blocks all of the time. The default area is equivalent to Case Else: if none of the case values match the value in the switch's quantity. So, let's look at the anatomy of the switch blocks:
switch (value) { case x: ...; break; case y: ...; break; default: ...; break; }
        private void btn11_Click(object sender, EventArgs e) {
            Element elem;
            int protons;
            float atomweight;
            string symb; 
            //Note: You cannot pass a property such as btn2.Text as an out parameter.
            //Thus, the string symb
            elem = Element.Helium;
            AtomicInformation(out protons, out atomweight, out symb, elem);
            MessageBox.Show(string.Format("{0}: {1} - Atomic Number {2}, Atomic Weight {3}.", elem, symb, protons, atomweight));
        } // End of btn 11's click.
Something else that may catch you: there apparently doesn't seem to be a way to detect ranges of values in C# switch statements the way you can for Select Cases in VB: You could say Case Element.Boron To Element.Fluoride and it would include all cases in between automatically. In C#, no such control exists and the equivalent is to type each case manually. IMO, it's better to just make a bunch of if statements as they are less bulky and more flexible than switch statements.
One thing that has always perplexed me, in regards to AtomicNumber = ( int ) el; is why you have to cast an enumeration to/from an integer, even though the values of an enumeration are restricted to integer values. It was like that in VB.NET and it's like that in C#.

Classes

For the most part, classes are identical to structures except for classes are referred to by references and not by values, the same way that they are done in VB.NET. Mismanaging classes will usually give you NullReferenceExceptions at runtime, so all class objects must be instantiated with a constructor, unlike structures.
    public class TestParallelogram {
        private Point[] vertices;
        // Upper left, upper right, lower right, lower left.

        public TestParallelogram(int left, int top, int basewidth, int baseheight, int offset, bool ishorizontal) {
            vertices = new Point[4];
            if (ishorizontal) { // The top and bottom sides of the parallelogram are flat, left and right sides are sloped
                if (offset > 0) { // Upper left corner to the right of lower left corner.
                    vertices = new Point[] {new Point(left+offset, top), new Point(left+basewidth+offset, top), 
                                            new Point(left+basewidth, top+baseheight), new Point(left, top+baseheight)};
                    // Make the vertices.
                } else { // Upper left corner farther left than lower left corner.
                    vertices = new Point[] {new Point(left, top), new Point(left+basewidth, top), 
                                            new Point(left-offset+basewidth, top+baseheight), new Point(left-offset, top+baseheight)};
                } // End of offset's if block.
            } else { // The left and right sides of the parallelogram are flat, top and bottom sides are sloped.
                if (offset > 0) { // Upper left corner is below the upper right corner.
                    vertices = new Point[] {new Point(left, top+offset), new Point(left+basewidth, top),
                                            new Point(left+basewidth,top+baseheight), new Point(left, top+baseheight+offset)};
                } else { // Upper left corner is above the upper right corner.
                    vertices = new Point[] {new Point(left, top+offset), new Point(left+basewidth, top),
                                            new Point(left+basewidth,top+baseheight), new Point(left, top+baseheight+offset)};
                } // End of offset's if block.
            } // End of horizontal check if block.
        } // End of TestParallelogram constructor.

        public void Inflate(int addwidth, int addheight) {
            vertices[1].Offset(addwidth, 0);
            // Offset is a member of the Point structure which basically moves a point.
            vertices[2].Offset(addwidth, addheight);
            vertices[3].Offset(0, addheight);
        } // End of inflate subroutine.

        public float Area() {
            return (vertices[1].X - vertices[0].X) * (vertices[3].Y - vertices[0].Y);
        } // End of Area function.
    } // End of Area class.
Here is a fairly daunting looking class - that's mainly due to the implementation of the constructor, where I set the values for points which define vertices for the array. Never mind the stuff inside the constructor - we'll expound on that later! The thing to note here is that there is essentially nothing different from the structure and the class, other than the fact that I have public class TestParallelogram rather than public struct TestParallelogram. The TestParallelogram class contains a subroutine 'Inflate', and a function 'Area'.
Now, to show you how to use classes from the outside:
        private void btn12_Click(object sender, EventArgs e) {
            TestParallelogram parry = new TestParallelogram(0, 0, 30, 20, 10, true);
            TestParallelogram isometric = parry; // isometric and parry 'refer' to the same parallelogram.
            MessageBox.Show(parry.Area().ToString()); // Area of first parallelogram should be 600.
            parry.Inflate(10, 10); // If I inflate parry's parallelogram... to 1200 area...
            MessageBox.Show(isometric.Area().ToString()); // The effects are reflected in isometric's parallelogram...
            // Because they are the same parallelogram.
            // The only parallelogram we actually have is the one instantiated. at the first line.
            parry = null;
            isometric = null;
            // Empty object references - always good practice.
        } 
The first line is responsible for creating the parallelogram - again, similar instantiation to the method we used for structures. The big difference is that parry is a reference (die-hard C guys may insist on using pointer for some reason) to the newly created parallelogram. Isometric is a reference to whatever parry is referenced to... which is the same parallelogram as above. Following the comments above, you can see that if you mess with parry's parallelogram, isometric's parallelogram is similarly affected.
Another point to make out is how you destroy class instances. A class instance is ready to be destroyed when there are no references to it. So, to destroy the TestParallelogram that was instantiated, you set the parry and isometric TestParallelogram references equal to null, equivalent to setting equal to Nothing.
        public int Width {
            get {
                return (vertices[1].X - vertices[0].X);
            } // Get the width.
            set {
                vertices[1].X = vertices[0].X + value;
                vertices[2].X = vertices[3].X + value;
            } // Set the width.
        } // End of width property.
        public int Height {
            get {
                return (vertices[3].Y - vertices[0].Y);
            } // Get the height.
            set {
                vertices[3].Y = vertices[0].Y + value;
                vertices[2].Y = vertices[1].Y + value;
            } // Set the Height.
        } // End of height property.
        public bool IsHorizontal {
            get {
                return (vertices[1].Y == vertices[0].Y);
            } // Tells if parallelogram is horizontal.
        } // End of readonly IsHorizontal? property.
Egad! What are those? The above code illustrates how you would make properties for classes in C#. Notice that the Width and Height properties are readable and writable because they both have a get and set block, but the IsHorizontal property is readonly because it only has the get block. If you similarly wanted to make a writeonly property, you would only include a set block and no get block. The format for the property is the most deceptive, in my opinion, so let's look at it from an "anatomical" viewpoint.
public datatype PropertyName { get { return ...; } set { ...; } }. One thing right off the bat: there are no parentheses in a property declaration. Do not put parentheses anywhere in the declaration. Don't try to slap '()' after the property name - it won't make a property for you and you'll get a bunch of errors! Just go directly into the braces. The exclusion of the get or set blocks are up to you. An interesting tidbit is that, in C#, you can omit the get and the set blocks and you won't receive any error or warning. The property will even show up in intellisense, even though there's no way for you to interact with it - simply netting you readonly errors and property-lacks-the-get-accessor error.
In the property's set block, you'll have to use the mystical variable named value. Value, as it did in VB.NET, represented the value on the right-hand side of the equality symbol when you set the value for the property. In C#, it's considerably less obvious. The only clues you have to its existence is remembering that you used to have 'Value' in VB.NET and that it happens to appear in the AutoComplete listbox (near the bottom, no less). Also, when you use value, it is highlighted as a keyword, which could throw you if you aren't expecting it. Well, now you know!
        private void btn12_Click(object sender, EventArgs e) {
            TestParallelogram parry = new TestParallelogram(0, 0, 30, 20, 10, true);
            MessageBox.Show(parry.Area().ToString()); // Area of first parallelogram should be 600.
            parry.Inflate(10, 10); // If I inflate parry's parallelogram... to 1200 area...
            // Because they are the same parallelogram.
            // The only parallelogram we actually have is the one instantiated. at the first line.
            parry.Height = 20;
            parry.Width = 20;
            if (parry.IsHorizontal) {
                MessageBox.Show("Working with a \"horizontal\" parallelogram!");
            }
            MessageBox.Show(parry.Area().ToString()); // The effects are reflected in isometric's parallelogram...
            parry = null;
            // Protip: Annul object references.
        } 
The above is an example of how you would use the properties that we just created. Next, Shared methods:
        private TestParallelogram() {
            vertices = new Point[4];
        } // Private constructor which creates an empty TestParallelogram
        public static TestParallelogram FromLTRB(int left, int top, int right, int bottom, int offset, bool horizontal) {
            TestParallelogram ret = new TestParallelogram();
            if (horizontal) {
                if (offset > 0) {
                    ret.vertices = new Point[] {new Point(left+offset, top), new Point(right+offset, top), 
                        new Point(right, bottom ), new Point(left, bottom )};
                } else {
                    ret.vertices = new Point[] {new Point(left, top), new Point(right, top), 
                                            new Point(right-offset, bottom), new Point(left-offset, bottom )};
                } // End of offset if block.
            } else {
                if (offset > 0) {
                    ret.vertices = new Point[] {new Point(left, top+offset), new Point(right, top),
                        new Point(right,bottom), new Point(left, bottom+offset)};
                } else {
                    ret.vertices = new Point[] {new Point(left, top), new Point(right, top-offset),
                                            new Point(right,bottom-offset), new Point(left, bottom)};
                } // End of second offset if block.
            }
            return ret;
        } // End of static LTRB Testparallelogram creator.
This is an example of a static method. If you browse the .NET Documentation, you'll probably see something to the effect of 'static (Shared in VB.NET). You see it so often, how could you possibly NOT know what a static method does in C#. It functions like a Shared method! Well, just in case you didn't know, now you know. The above example uses LTRB arguments to create a parallelogram in the same way that regular constructor created a parallelogram. The only difference is that left+basewidth became right, and top+baseheight became bottom. As far as static methods in C#, this one is very lenient: you have the option of writing 'static public' or 'public static'.
        private void btn13_Click(object sender, EventArgs e) {
            TestParallelogram melee = TestParallelogram.FromLTRB(50, 50, 100, 100, 20, false);  // Static method.
            melee.Inflate(15, 20); // Make parallelogram bigger
            MessageBox.Show(melee.Area().ToString()); // Show area.
            melee = null;  //Protip: Annul object references.
        }  // End of btn 13's click procedure.
The above is how you could use the static .FromLTRB method to create a parallelogram.
    /// <summary>
    /// IGeometric provides assurance that the class will return its Area.
    /// </summary>
    public interface IGeometric {
        int Area();
    } // End of IGeometric interface.
Interfaces in C# are as simple as the interfaces in VB.NET. You only have to state the keyword interface. The semicolons are still required. Do not specify the scope in front of the interface type, otherwise you'll get a build error telling you to remove it.
        private void btn13_Click(object sender, EventArgs e) {
            TestParallelogram melee = TestParallelogram.FromLTRB(50, 50, 100, 100, 20, false);  // Static method.
            IGeometric areaprobe = melee; // Areaprobe is installed in melee parallelogram to return its area.
            melee.Inflate(15, 20); // Make parallelogram bigger
            MessageBox.Show(areaprobe.Area().ToString()); // Show area.
            areaprobe = null; //Protip: Annul interface references.
            melee = null;  //Protip: Annul object references.
        }  // End of btn 13's click procedure.
Example of using an interface directly - you could also use another method which utilizes IGeometric to do something with the areas.

Exception Handling

Generally, it's good to prevent exceptions from being thrown in your application, but sometimes you cannot avoid some exceptions. Sometimes, the programmer using your class/DLL passes in garbage values. So, first let's throw some exceptions:
        public int Width {
            get {
                return (vertices[1].X - vertices[0].X);
            } // Get the width.
            set {
                if (value < 0) {
                    throw new SystemException("Width cannot be less than zero.");
                } else {
                    vertices[1].X = vertices[0].X + value;
                    vertices[2].X = vertices[3].X + value;
                } // End of validation block
            } // Set the width.
        } // End of width property.
        public int Height {
            get {
                return (vertices[3].Y - vertices[0].Y);
            } // Get the height.
            set {
                if (value < 0) {
                    throw new SystemException("Height cannot be less than zero.");
                } else {
                    vertices[3].Y = vertices[0].Y + value;
                    vertices[2].Y = vertices[1].Y + value;
                }
            } // Set the Height.
        } // End of height property.
This throws a general exception from trying to apply negative Widths and Heights to a parallelogram. Running the code below will give you an exception and point you... rather directly to the source of your exception.
        private void btn13_Click(object sender, EventArgs e) {
            TestParallelogram melee = TestParallelogram.FromLTRB(50, 50, 100, 100, 20, false);  // Static method.
            melee.Width = ~0;  // Not of 0 is -1.
            MessageBox.Show(melee.Area().ToString()); // Show area.
            melee = null;  //Protip: Annul object references.
        }  // End of btn 13's click procedure.
So, we'll use try ... catch ... finally blocks to handle the error.
        private void btn13_Click(object sender, EventArgs e) {
            TestParallelogram melee = TestParallelogram.FromLTRB(50, 50, 100, 100, 20, false);  // Static method.
            try {
                melee.Width = ~0;  // Not of 0 is -1.
                MessageBox.Show(melee.Area().ToString()); // Show area.
            } catch { // Catches anything thrown out of the try block.
                MessageBox.Show("Your parallelogram width is too small.");
            } finally {
                melee = null;  //Protip: Annul object references.
            } // End of the exception handler.
        }  // End of btn 13's click procedure.
Catching thrown exceptions is as easy as making a whole bunch of blocks. The format for exception-handling blocks such as the one above is:
try { ...; } catch (SystemException err) { ...; } finally { ...; } Catching thrown exceptions makes it easy to handle errors that you cannot protect yourself from, but a better idea is to know where the errors could come from, minimize the number that you cannot handle, and then handle exceptions on code that you can't prevent from generating exceptions.