Saturday, June 28, 2014

Structs vs. Classes in C#

This MVA video does an excellent job of explaining the difference. This post is a short summary of the video.

The most important thing to understand is passing by reference versus passing by value. The example I use for explaining the difference between pass by reference and pass by value is this: You go to an art gallery and buy an original work of art. When you take it home, your 2-year-old scribbles all over it with crayon. The original work of art is forever changed. That's passing by reference. But if you were to buy a print of the original work of art which your 2-year-old then scribbles on, the original work of art is not affected. Although it may suck for you that you paid good money for a print which is now messed up, the original work of art remains intact and more prints can be made from it. That's passing by value.

If you've looked at structs before, you know that a struct looks and acts a lot like a class. But as is pointed out in the video, there are some major differences. So here is the promised summary of the video.

1. Structs are values types and classes are reference types. Thinking of my example above, this means that when changes are made, only a copy is changed and not the original values in a struct. But with a class, whatever values you change are changed within the class itself. The MVA video does a great job of demonstrating this by code. I copied the code and put it on GitHub so I could see the whole thing at once. I just got tired of rewinding and fastforwarding when I wanted to see something. Just remember, this is not my code but the code from the MVA video.

2. Structs are passed on the stack and classes are passed on the heap. When a copy of a struct is passed onto the stack, the whole data structure is passed. (This is also means structs should be smaller data structures than classes.) When a class is passed on the heap, a copy of the memory address is passed. While this makes the process more efficient than passing the entire data structure, it also means that the method receives a copy of the instance of the class and, thus, has access to change the class itself.

3. What is the stack and what is the heap? Here is a great article. I won't try to reinvent the wheel. Just read this.

4. What is with the hashtags? It just means you can specify a block of code, a region, like the struct, that can be collapsed while you look at other code. I added in the regions to the code on GitHub, so you can try it out there.









Monday, June 23, 2014

StringBuilder in C# - Tricky truncating with Length and Append

StringBuilder, unlike String, is a class that allows you to change the length of a string. If the length property is already set and a new string is created that is longer than the length, the length increases. If the new string is shorter than the property value already set, it decreases. The MSDN source code provides a more technical way of putting it. (See lines 464-467.)

Here's a simple example to demonstrate:

      StringBuilder example = new StringBuilder("Hello");
      //length changes from default value of 0 to 5 on creation of the object
      Console.WriteLine(example.Length);
      //output is 5

Using the append method, I add the string "Hello" onto an empty string.

      StringBuilder example = new StringBuilder("");
      //this is an empty string; length is still 0 
      example.Append("Hello");
      Console.WriteLine(example.Length);
      //output is still 5 

Using the append method, I add the string "Hello" onto a string containing only a space character.
      StringBuilder example = new StringBuilder(" ");
      //this is NOT an empty string
      //there is a space character in this string; current length is now 1 
      Console.WriteLine(example.Length);
      //output is 1
      example.Append("Hello");
      Console.WriteLine(example.Length);
      //output is now 6, because there is a space character at the beginning of the string
      Console.WriteLine(example);//output is " Hello" - there will be a space before "H"

Just remember that an empty string ("") is not the same as (" "). The latter contains a space character. This makes a big difference if you're appending your string and then getting the length. Not that I expect this is done on a regular basis, but the moral of the story is to make sure you know what prior strings contained before appending or you might get a surprise. (Not that this ever happened to me.)

So what if I wanted to get rid of the space character? Truncate.

         StringBuilder x = new StringBuilder(" ");
         Console.WriteLine(x.Length);//output is 1 because of the space character
         x.Length = 0;
         x.Append("Hello");
         Console.WriteLine(x);//output is "Hello"; notice there is no space before "Hello" now
         Console.WriteLine(x.Length);//output is 5;

Here is a screenshot to show the code and output.



Monday, June 9, 2014

C# DateTimePicker and Current Time a.k.a Learning to Load

This is a "helpful hint" post. I was working on a Windows Form and needed the form to update to the current time each time the app was run. I started with the TimeDatePicker in the form, choosing Time for the property Format because I only wanted to display the time, not the date. I didn't have to set Value because that property was automatically set to the current date and time. The code I used was:
private void DateTimePicker_Click(object send, EventArgs e) 
{ DateTime.dateTimePicker1 = DateTime.Now;}
Unfortunately, this combo did not work. Each time I ran the app, it showed the time the app was created and not the current time.

The first lesson here is to not assume that Click is an event for every controller. It's not an event for DateTimePicker. It seemed logical to me, though, so I used that in my code without checking to see if it was an actual event. You click to change the date and/or time, right? Yes, you do. But that was the wrong logic.

The correct logic is to ask: A) What should the controller do? The controller should show the current time. B) When should the controller perform this task? The controller should perform this task when the form loads, which means the data needs to be picked up before the form displays.

Here is one way to write the code correctly:
private void Form1_Load(object sender, EventArgs e)
      {     //Form1 is the name of the class used to create this form
         dateTimePicker1.Value = DateTime.Now;
      }//also see DotNetPerls for another snippet

Since my textbook didn't go into a lot (i.e., any) detail about loading, I had to do a little research. Although I ran across references to Load when I was searching high and low for a way to make the time update, I couldn't find it as an event for DateTimePicker. That's because Load is an event of class Form, which is a class in the Forms namespace. (When you create a form, you will see that the class automatically generated for you is a derived class of class Form.) In the order of events, Load occurs before the form is displayed, which is logical.

The moral of the story is that if you want the current date, i.e. data that must be captured anew each time the app is run, you need the Load event. Just remember that Load is an event of class Form, not the controller DateTimePicker,

I strongly recommend reading these two posts by DotNetPerls: One on Load and one on DateTimePicker to help you understand this better.

Tuesday, June 3, 2014

Getting dates and calculating a time interval in C# - Part II

TimeSpan

You can get the source code on GitHub. (I've updated the code a bit.)

TimeSpan is struct with a method subtract that will calculate the number of days between two dates. This means, though, that we are now dealing with a different type from DateTime. DateTime just gives you dates and, as you know from the previous post, I needed to calculate an interval between dates. So how could I use the  TimeSpan type with the DateTime objects I had created?

My first thought was to convert my TimeSpan object to a DateTime object because I knew how to format DateTime to display only the date. But as someone pointed out on Stack Overflow, it doesn't make sense to do it that way. TimeSpan represents, guess what, a span of time. DateTime represents, yes, you guessed it, a date and a time. The date July 12, 2013 is different from the time span 2 days, 12 hours, 30 minutes and 40 seconds.

So here's how it's done:
TimeSpan daysGoneBy = todayDateOnly.Subtract(boughtDateOnly);
Start with a TimeSpan variable, daysGoneBy. On the other side of the equation is largerDate.methodSubtract(argumentIsSmallerDate).

Now, just display the result:
string output;
output = "The number of days elapsed since the vehicle was bought: " + daysGoneBy.ToString("%d");
As you may recall, "d" is a format specifier. Here, "%d" means only the whole number of days will be displayed. (Remember that % is the symbol for modulo.)

It took some work for me to figure this out on my own, putting all the pieces of the puzzle together, and it was a lot of fun. I hope you find it helpful.