Structures

Well, let's go ahead and make the leap into Structures in C#. Here is an example structure for an octagon shaped object:
    public struct octagon {
        public float width;
        public float height;
        public float basewidth;
        public float baseheight;
    } // End of octagon structure
This is a fairly simple structure. We simply have four floats representing different geometrical features of an octagon. Declaring and using the octagon is probably as you might suspect:
        private void btn10_Click(object sender, EventArgs e) {
            octagon Ok; // Make an octagon. :)
            Ok.width = 6f;  // Sets wide width to 6f.
            btn10.Text = Ok.width.ToString(); // Display in button.
        }
The octagon is declared just as you would declare an integer, or any other type for that matter. You set values in structures in C# the same way you would in VB.NET: by using the period to access members of the structure. Of course, you can do more with structures than simply declare a bunch of variables inside. This is what we'll go over in the next few examples:
    /// <summary>
    /// Structure which holds information to construct an octagon.
    /// </summary>
    public struct octagon {
        private float width;
        private float height;
        private float basewidth;
        private float baseheight;
        
        public void setvalues(float widthmax, float widthmin, float heightmax, float heightmin) {
            this.width = widthmax;
            this.height = heightmax;
            this.basewidth = widthmin;
            this.baseheight = heightmin;
            return; // Return is not necessary for subroutines.
        } // End of setvalues subroutine

        public float area() {
            return width * height - (width - basewidth) * (height - baseheight) * 0.5f;
        } // Area function calculates area of an octagon.

    } // End of octagon structure
This is how you'd make a subroutine setvalues and a function area in a structure, along with making private values.
        private void btn10_Click(object sender, EventArgs e) {
            octagon Ok = new octagon(); // Make a new octagon. :)
            Ok.setvalues(4f, 2f, 4f, 2f); // Set the values of the octagon.
            btn10.Text = Ok.area().ToString(); // Display the area of the octagon in the button.
        }
And this is how you'd call it. You may notice the parentheses after area and wonder if those parentheses are required. The answer is yes. Do not forget to add parentheses to procedures that don't accept any arguments. Again, you'll get an error if you omit them.
Another interesting factoid about the above code in combination with the associated class: why do you have octagon Ok = new octagon();? The reason for that is that, in C#, you have to initialize the structure Ok before you can use any of its methods, regardless of what the method actually does. This may seem weird now, but it'll make more sense because the next thing that I'll show is how to make the "constructor" for a structure.
The equivalent to Public Sub New(arguments) ... End Sub in C# follows the format public classname(arguments) { ... }, as in the below example.
    /// <summary>
    /// Structure which holds information to construct an octagon.
    /// </summary>
    public struct octagon {
        private float width;
        private float height;
        private float basewidth;
        private float baseheight;

        public octagon(float widthmax, float widthmin, float heightmax, float heightmin) {
            this.width = widthmax;
            this.height = heightmax;
            this.basewidth = widthmin;
            this.baseheight = heightmin;
        } // End of setvalues subroutine

        public float area() {
            return width * height - (width - basewidth) * (height - baseheight) * 0.5f;
        } // Area function calculates area of an octagon.

    } // End of octagon structure
        private void btn10_Click(object sender, EventArgs e) {
            octagon Ok = new octagon(4f, 2f, 4f, 2f); // Make a new octagon. :)
            btn10.Text = Ok.area().ToString(); // Display the area of the octagon in the button.
        }
Now, this is a much more elegant solution that doesn't require you to create a new octagon with no parameters and then assign the values to the octagon after you instantiate it. Instead, this method allows you to place values directly into the octagon structure as soon as you instantiate the octagon. Both of the methods that I just listed were available in VB.NET, except that in C#, adding () after subroutines, such as the constructor or any other subroutine, is required. You'll get an error stating that the compiler is expecting () (along with other things). However, creating the structure constructor is relatively more different than the VB.NET way, so it's worth mentioning again: public classname(arguments) { ... }. A good way to think of the C# constructor is that it is a function (rather than a sub as in the case of VB.NET) that has no name. So that, when you're thinking of the constructor, you write a function that returns the type that you're making the constructor for, and then you just don't put the name. Think: public octagon MyFunction(arguments) { ... }; without the MyFunction part: public octagon(arguments) { ... }.
        public void Inflate() {
            // Stretches width and height of the octagon.
            this.width *= 2f;
            this.height *= 2f;
            this.basewidth *= 2f;
            this.baseheight *= 2f;
            return;
        }
        public void Inflate(float widthfactor, float heightfactor) {
            // Stretches width and height to the specified factor.
            this.width *= widthfactor;
            this.basewidth *= widthfactor;
            this.height *= heightfactor;
            this.baseheight *= heightfactor;
            return;
        }
        public void Inflate(float areafactor) {
            // Stretches octagon to increase area by specified factor.
            this.width *= ( float )Math.Sqrt(areafactor);
            this.basewidth *= ( float )Math.Sqrt(areafactor);
            this.height *= ( float )Math.Sqrt(areafactor);
            this.baseheight *= ( float )Math.Sqrt(areafactor);
            return;
        }
Overloaded functions and subroutines in C# are done the same way they are in VB.NET, with one exception: there is no Overloads keyword in VB.NET. It was not necessary in VB.NET versions with the exception of VB.NET 2002, and it has never been required in C#.
    public struct octagon : IComparable, IFormattable  {
        
        private float width;
        private float height;
        private float basewidth;
        private float baseheight;

        public int CompareTo(object obj) {
            octagon test;
            if (obj is octagon) {
                test = ( octagon )obj;
                return this.area().CompareTo(test.area());
            } else {
                return 0;
            } // End of if block to ensure obj is an octagon.
        }// End of IComparable's .CompareTo

        public string ToString(string format, IFormatProvider formatProvider) {
            return String.Format("Octagon: {0} by {1} with internal {2} by {3}.", width, height, basewidth, baseheight);
        } // End of octagon.ToString()
Here is an example of implementing an interface in C#. In VB.NET, you specify the Interface inside of the class or structure at the top, press Enter, and your class or structure is instantly populated with the requisite functions that you need to implement. In C#, the interface that you want to implement is instead declared immediately after the structure name after a colon. The colon performs multiple features as we'll see when we get to classes. Once you type the colon and type an I, intellisense pops up some interfaces that you can implement. When you choose one, you can mouse over the interface and select what type of implementation you would like to perform for the interface. The one familiar to VB.NET (2003) is the regular 'implement the interface', and you then type in your code which implements the interface. In C#, you don't have to specify which function implements the interface.
Something that may be important if you end up using a method which converts a class or a structure to a more generic type: to determine if an object matches a particular type, use the is keyword. The is keyword is sort of switched over in C#. In VB.NET, to determine if a type matches another, you have to use the TypeOf keyword, as in If Typeof obj Is Octagon Then. But, in C#, you just use the is keyword, as in if (obj is octagon) { ... }.
What about the line under it? Well, that is another big point to make in regards to differences in between VB.NET and C#. Recall that, in VB.NET, if you needed to turn an object back into a specific type, you had to use thing = DirectCast(obj, type). C# type casting is much different than it is in VB.NET. In C#, casting is done without any descriptive words: thing = ( type )obj;. One thing that makes casting in C# more convenient than in VB.NET is that you can cast a whole bunch of different variables - numeric types are cast from one type to the other in the same way.
        private void btn10_Click(object sender, EventArgs e) {
            octagon Ok = new octagon(4f, 2f, 4f, 2f); // Make a new octagon. :)
            octagon[] Octies = new octagon[3]; // Three octagons in an array.
            Octies[0] = new octagon(6f, 3f, 4f, 2f);  // This should be the biggest
            Octies[1] = Ok;  // Followed by this one.
            Octies[2] = Octies[0];  // This one will be a copy of the first.
            Octies[2].Inflate(0.25f);  // We will shrink it to 25% size.
            Array.Sort(Octies); // Then sort the array: this requires octagons to implement the IComparable interface.
            btn10.Text = String.Format("Winner {0}", Octies[2]); // Display the area of the octagon in the button.
            // Calling string.Format requires octagons to implement the IFormattable Interface.
        } // End of btn 10's click procedure.
Example of calling methods that utilize the interfaces that we've implemented.