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.

Wednesday, May 21, 2014

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

I wanted to create a console app in Visual C# which required the app to choose a path based on the number of days elapsed between the current date and a date entered by the user. I assumed I would do a quick search and find a way to do this on MSDN or Stack Overflow. I assumed many people had done this many times and code snippets would be posted all over the web. Wrong. Sure, I found a way to subtract one date from another if I entered the dates as arguments or the app was a form. But I couldn't find a way to do it when 1) the app was a console app, 2) the app provided the current date and 2) the user entered another date which would be subtracted from the current date.

This is a two-part post explaining the program I wrote to resolve the problem. Part I explains how to get the dates. The second part will explain how to subtract the dates to get the time interval. The full source code is on GitHub.

Today is the day
Getting today's date is easy:

     Console.WriteLine("Today's date is {0}.", DateTime.Today);

Microsoft has already provided us with the DateTime struct and its property, Today. By reviewing the source code, you can see that Today is a static property.  Static properties can be called without an object being created, hence, the reason the code snippet above will display the current date and time.

However, for my purposes, there are a couple of problems with this code. First, this format will give you a time of 12:00:00 AM as well as the date. For my app, I didn't need the time. Second, I didn't need to merely display the current date, I needed to store it so that another date could be subtracted from it. As painfully obvious as this is now, I wasn't sure how to do that. If you aren't either, read on.

Construct Today
Starting with the basics, DateTime is structure (a.k.a. struct) in the System namespace. You do not need to use keyword "new" to instantiate a struct object. Create the object like so to display only the date:

     DateTime dateOnly = DateTime.Today;
     Console.WriteLine("Today's date is {0}.", dateOnly.ToString("d");

     (The "d" is a short date format specifier. In other words, this format will give you the date and not the time.)

You may also want to read DotNetPerls which explains why you would choose the Today property over the Now property.

User Input
Since DateTime is a struct, that means it is a type. After I ask the user to input a date, I declare a DateTime variable and convert the line entered by the user to DateTime type. Just as with the code snippet above, though, this will display the date and a time. So the next step is to create a DateTime object and use the short date format specifier in the Console.WriteLine argument.

         Console.WriteLine("Enter the date you bought your vehicle.");
         Console.WriteLine("Use this format, 01/01/2011.");
         DateTime whenBought = Convert.ToDateTime(Console.ReadLine());
         DateTime boughtDateOnly = whenBought.Date;
         Console.WriteLine("Vehicle was bought on {0}.", boughtDateOnly.ToString("d"));

Here is a screen shot of the output.


The next post will go over TimeSpan and its Subtract method.

Sunday, May 11, 2014

Optional Parameters and Named Parameters in C#

I just don't like it when simple things are explained in a complex manner. So let me break it down for other C# noobs, in case you have a textbook like mine that provides an insufficient explanation or if you just don't understand these two types of parameters.

Optional Parameters

You will be surprised to learn that, as the name suggests, this means the parameters* are optional. The client code does NOT have to provide arguments for these parameters. Why? Because a default value is already included for you.

Example: public void optParam (int x, int y =2, int z = 3)
                       {some code};//this method has two optional parameters

In this case, there are two optional parameters, "y" and "z". Parameter "y" has a default value of 2 and parameter "z" has a default value of 3. If no value is provided for "y" or "z", they will retain their default values. You will notice that parameter "x" has no default value provided. This means that the client code MUST provide an argument for this parameter. Also be aware that the required parameter must come before the optional parameters.

Obviously, there is a problem. If you want to provide an argument for "z" and not for "y", how can you make the arguments be evaluated so that the first argument will be applied to "x" and the second argument to "z"? You can't. As MSDN informs us, you would have no choice but to specify the argument for the optional parameter "y" before providing the argument for "z". Needless to say, there would be no point in having an optional parameter "y" in that case. This is where named parameters come to the rescue.

*Per MSDN, optional and named parameters can be used with methods, constructors, indexers and delegates.

Named Parameters

When calling the method, the client code need only name the optional parameters for which it wishes to provide a value, avoiding the problem just described.

Example:  public void optParam (int x, int y =2, int z = 3) {some code};
                optParam (20, z: 30);

This result is x = 20, y =2 and z = 30. You avoid having to rewrite the default value and another benefit is that you can put the named parameters in any order. The same rule about required parameters coming before optional parameters applies here. The arguments supplied for the optional parameters can come in any order as to each other, but they must come after the arguments for the required parameters.

Example:  public void optParam (int x, int y =2, int z = 3, int zz = 5) {some code};
                optParam (20, zz: 30, y: 10);//okay
                optParam (y: 30, zz: 10, 20);//not okay

Here you can see a sample of code I wrote to show how the two types of parameters work together and a screen shot of the results: https://github.com/htravar/Parameters. You may also find this article helpful.

This topic does get more complex, but I hope I've explained the basics in a basic way. Enjoy the parameter shortcut.

Wednesday, April 30, 2014

Math.Min vs. Random.Next in C# - To be (static) or not to be?

As I carefully read through my notes, I had to stop and ask, "Why do I need to create an object for class Random? It bothered me to no end because I had just read about Math.Min being a static method. (Static methods mean you are not required to create an object prior to calling the method.) Yet here I was, perusing an example that created an object of class Random before calling the Next method.

My problem was my assumption. My assumption was that Random.Next was a static method since I had just been reading about static methods in a different section of my lesson/text. It was not explicitly pointed out that I was no longer reading about static methods and I just assumed every method discussed was static.

As a lawyer, I should have been more discerning. Luckily, the light bulb went off and I started a search for "Is Random.Next a static method in C#?" Turns out, I was not the only one who had this question. Stack Overflow turned up first in my search and someone asking the same question received enlightening answers on why Random.Next cannot be static. Although it would have been nice if someone had noted that we were no longer talking about static methods, the fact is that Random.Next was actually discussed in a section on the .NET framework class library in general, not in the section on static methods.

So, for all you noobs who were perplexed as I was, the answer is that Random.Next is not a static method. This is why you must create an object before calling the Next method. Just watch what you're reading and don't assume too much.