Continuing on the subject of threading, a coworker asked me an interesting question the other day. She has an application that's basically a packet-logger. She connects up to some service, sends it a request, and if she gets anything back, she logs it to an XML file. To communicate with this service takes a while, so she has two threads going at once, each one doing both polling and logging. The constraint here is that the data has to be logged in real time. (Why real time? I don't know, maybe in case of a robot attack on the data center. You think a robot will give you an extra 5 ms to write to your log file?!) Because I like to act like I know what I'm talking about, she asked me for help.
If you have two threads trying to access the same physical resource at random times, something bad is going to happen. Sooner or later, both threads will try to write at the same time and something will blow up; all you can do is hope that this blown-up something is neither you nor your pants. How do you fix this brewing catastrophe?? You fix it with locks. By locking your resource, you give one thread exclusive access, and then you alert the other thread to go ahead (in .NET, you communicate with other threads using Monitor.Pulse and Monitor.WaitPulse).
The problem here is that she said it HAS to be real-time. If you're locking something, you're not going to be logging in real-time. If a thread has the file locked that the other thread wishes to access, there must be a wait. It may not be much of a wait, but depending on how long you're talking to that service and writing to the disk, it could be a while. So how would you get around it?
One idea I had was to divorce the logging part from the service communication part. What if you still had your two threads communicating with this slow, crappy service, and whenever they had something to log, they inserted it into a shared, thread-safe queue? Let's go further and say this is a smart queue where we've added some wizardry so that anytime an element is enqueued, we write it to the disk.
The problem is that even with the queue, if you want multiple threads to access it safely, you have to lock it. The good part is that you're locking an in-memory object, not a physical resource. I would assume this is faster, although I have no numbers to back that up. In the spirit of bloggers everywhere, I will just make up a number: this solution is 27.8% faster than locking the XML file.
It's not real-time, but it's thread-safe. You can have fast and dangerous, or you can have slightly less fast and much safer. I realize most programmers have to be clubbed over the head to renounce the first, but this might be a good situation to do so, simply because threads get weird.
I have plenty of stuff written up for the site, but then whenever I get home, I find myself distracted by something like Bear Baiting with the Stars. Anyway, let this serve as a note to self: if, in the future, you add a control programmatically to the form and it's not showing up even though it's Visible == true, it's probably because you didn't add it to the form's Controls collection. I do this once a week, like a regular lord of the dumb asses. The cycle stops now!
I found a neat little C# 2.0 doo-dad today. We all know that one of the new features is v2.0 of the language is partial classes, where you can define a class in multiple places. Why is this useful? Well, it's very handy if you create a form and allow Visual Studio to insert all of its generated code into our class. With partial classes, you can segregate the messy, generated stuff from the beautiful, self-written masterpiece.
A question I had today was: what happens if, in a partial class scenario, you accidentally apply differing class modifiers in your class files? Let's say in Class1.cs, you say that Class1 is a public sealed class (can't inherit from it), and then in Class1.Designer.cs, you simply say it's a public class (so that it could be inherited). To contrast that, what if you say a class is abstract in one place and then not in another? Well, from my experiments, the compiler will apply the modifier, even if it's only in one spot.
What if the modifiers are completely opposing, like abstract and sealed? Then, the compiler will complain. As long as the modifiers don't create an erroneous situation, you can specify them independently all over the place. I could be wrong about that, but let's pretend I know what I'm talking about.
Now is this good or bad? That's a little harder to summarize. If I'm working in a partial class (usually in a Visual Studio-generated form), I'd much rather NOT have to touch the code generated by Visual Studio. If I can specify something once in a class declaration and see it carried over to the generated code, that's a good thing. At the same time, I could see how this would be harder to maintain, because you have to search out all declarations of the class to see what the modifier actually is. Let's call it a good/bad.
Hey, remember last time when I was talking about how some objects implement IDisposable, but often you can't tell because there's no public Dispose method? And remember how I had no idea how that worked and I got really frustrated and tried not to cry in front of you? Well, yeah. Patrick did a little research and discovered this is actually because of something called explicit interface implementation.
To steal a line from that link, "a class that implements an interface can explicitly implement a member of that interface." So, when a StreamReader implements IDisposable, it must be explicitly implementing its Dispose method. By doing that, it can fulfill the contract with the interface. It sounds complicated, and it pretty much is. Here's a quick example.
//Explicit implementation of IDisposable.Dispose
void IDisposable.Dispose()
{
}
//IDisposable expects a Dispose method with
//no parameters, so this doesn't work.
public void Dispose(bool confirm)
{
if (confirm)
{
//release all resources in here.
}
}
}
Now, if you look at that code, there are a couple of salient points. First, it compiles. That's always good. Second, it implements IDisposable and does so without a public void Dispose() method. It does have a public void Dispose method, but it takes in a parameter, so it doesn't fulfill the contract with the interface. However, it works because it explicitly implements the IDisposable.Dispose() method. Sneaky, eh? For verification, wrap an ExplicitDisposable object in a using block and let the compiler roll.
All of this was news to me. I knew nothing about explicit interface implementation, and my head was beginning to combust from trying to comprehend this. Thankfully, Mr. Lioi pointed me to a very informative usenet thread that got me straightened out. I'm still not sure just how useful it is and whether it does anything but confuse developers, but it's out there. Oh, it's definitely out there, so it's good to learn.
I have in my right hand an interesting C# tidbit that I offer up for the benefit of the world. Did you know that some objects actually implement the IDisposable interface, but that it's impossible to tell from Visual Studio's Intellisense? You say, "Big deal. Shut your yapper, Powell, and get back to your Thundercats fan fiction!" Well, IDisposable is one of the most important interfaces to know about. If an object implements IDisposable, its creator is telling you that this is an object you must dispose. A lot of times, that's because the object is tying up a physical resource like a database connection or a file on the hard drive. If you don't dispose of those objects properly, you get resource conflicts.
Usually, you can tell through Intellisense if an object has a Dispose method. I always thought that if object.Dispose() isn't available, it solves that conundrum. However, there are lots of objects that DON't have a public Dispose method that DO implement IDisposable. Case in point, the StreamWriter and StreamReader objects (LINK TO MSDN DOCS). If you check their members, their Dispose() methods are actually protected. Intellisense is not enough in these cases.
If you're ever unsure about whether an object implements IDisposable, just wrap it in a using block like so:
Now, why is the Dispose method protected? I have no idea. I have it on my agenda tomorrow to ask Bill Gates and Anders Hejlsberg the next time we're playing horseshoes. For me, the important thing isn't necessarily the visibility of that Dispose() method, but the IDisposable interface. An easy way to check that is with a using block.
Who wants a WinForms trick?! If you're not running around, screaming at the top of your lungs "I DO! I DO!", then I don't know if I want you on this website.
Anyway, this one is an oldie but a goodie. How do you validate a Windows Form on the fly in C# (or VB.NET, for that matter)? Let's say you have a form with one text field and an OK button. When the user clicks the OK button, you want to validate that text field to see that it's at least 5 characters in length. How would you handle that validation?
For slightly complicated validations, you can use the Validating events for your controls, along with the ErrorProvider on your form. There are lots of places that tell you how to do that. However, if you just want a quick and dirty validation, you can do it simply by manipulating your OK button's DialogResult setting.
Here's what the event handler for your OK button would look like:
Simple, and definitely not something you'd want for anything but a trivial example.
I hope to post something really cool a little later this week. I've been working on a personal app in my spare time and I've got to think I'm close to my first release. I've GOT to think that, or else I'm setting fire to my computer desk. More details as they emerge.
Man, NDoc rules.
We're beginning the design stage of a huge project, and one question we kept encountering was: how will we be able to design the methods in our classes? Our design documents contain a lot of UML class diagrams, which are really useful when it comes to creating your objects, but they don't describe how a method and its algorithms actually work. We could just write some notes on the methods in the design documents, but then how do you know if the developer (or you, for that matter) will make use of your method notes when he's implementing the design? That's pretty far removed from the actual code.
Well, one smart feller on the team (pretend his website says something) proposed that we could generate a few skeleton classes and their methods, and then document the methods inside the code file using the XML documentation features inside of Visual Studio .NET. Woo boy, it was a pickle to set up, but once I got that going, I had immediate results. Not only did it format all of my XML comments in my methods into something really readable (the resulting documentation looks just like the MSDN site), but the XML comments are still there in the methods for when it's time to code them. Game, set, match, Mr. Powell.
It's a great idea, and one that more folks should consider. Just because you put your comments into the code doesn't mean you're neither designing nor documenting. Wiht NDoc, you do both AND you ensure your notes are in a place where they must be read during implementation.
I would list some links to a similar tool for Java, but really, those people terrify me.
Sometimes, the interactions between similar collections in C# and VB.NET can get weird. Not cats-and-dogs-living-with-each-other weird, but less than intuitive. For example, let's say you have a multi-select listbox on a form (we'll say it lists a bunch of cereals), and you need to convert its SelectedItems collection into an ArrayList for some part of your business logic. That should be pretty straight-forward, yes?
Instead, you have to get tricky and do something like this:
Recently at work, we got into a spirited discussion via email about the performance enhancements that can be obtained through multi-threading in the .NET Framework. If you read that sentence and think to yourself, "Those dudes know how to rock," you've definitely got a point.
There were a lot of opinions exchanged, but one that kept coming up was that threading actually slows down an application because it makes inefficient use of the processor. I'm no threading master; while I can write a good multi-threaded app, I'd rather tickle a rhino's behind than try to compute the Big O notation for multi-threaded, computationally intensive code. However, as a lazy programmer, I knew I could write up a proof-of-concept to evaluate the idea. That's just what I did.
Ladies and gents, I offer you ThreadTest (contains EXE and source code). Not only is it a pretty good introduction to threading in C#, it outputs performance information for a computationally-intensive task (determining the factors for a huge number) that's done once in a single thread and once in a multi-thread environment.
The EXE is meant to be run from the command line. You must supply it with two parameters: the number to be factored and the number of threads to spin off. When you run it (by typing something like TestThread 1000000000 5), it'll factor the number once in a single thread, and then it'll break the number into chunks, spin off the desired number of threads, and let each thread factor a chunk. Once completed, it tells you how long each method took, as well as which was faster.
It's pretty fun to play around with, plus it helps to provide some hard data on multi-threading. The results I obtained showed that a threaded, computationally-intensive task can perform in a fraction of the time that the same non-threaded, computationally-intensive can perform in. For a simple task, any gains to be had from threading are negated due to the complexity of spinning off the threads. Altering the number of threads didn't seem to have as large a performance effect as one might think.
Here are a few sample results I obtained on my single-processor laptop. This is all extremely unscientific, and only tried on one machine.
Results at bottom of page.
One of the unfortunate points of the .NET Framework is that Microsoft neglected to distribute some pretty common controls for it. For example, a numeric textbox; nowhere in Visual Studio .NET will you find a textbox control that only accepts numeric values. That's bad, because there are a lot of times when you want to limit your data entry and display actions to just numeric values, such as when you're dealing with dollar amounts and percentages.
It's not too hard to half-ass something that kinda works here, but inevitably some edge case surfaces in your control (egads, someone entered two negative signs!) that causes your whole app to mess itself and go into seclusion. It is a nasty, brutal procedure to perfect the control, and for some reason, I dedicated my Sunday afternoon to it.
Ladies and gentlemen, I introduce you to my NumericTextbox (dll, code). With it, you can accept numeric user input into a textbox and display it as a formatted number, currency amount, or percentage. It filters for valid numeric data only, and allows the developer to specify decimal precision and comma formatting. Just slap it on your form, and when you want to access the value, call the appropriate Parse method for the data type you want (Float.Parse(numericTextbox.Text), Int32.Parse(numericTextbox.Text), etc.)
I've only tried it on my laptop, so if it causes your immediate office area to burst into flames, I will accept absolutely no responsibility. Feel free to mark up the code however you want.
Lest anyone ever accuse me of arrogance, let me declare it flat out: I don't understand structs. Not in C#, at least. One of the standard interview questions for a C# developer is to name the difference between a struct and a class. That's easy; a struct is a value type, a class is a reference type. However, the implications of that are totally mind-boggling. I learned this first-hand with an interviewee earlier today.
When I asked him that question, he gave the right answer. He went on to say that one interesting thing about structs is that you can't compare them with the == operator. I smiled and nodded at the time, but later on after the intervew, I began to think about it. A struct is a value type, just like an int. Both are created on the stack, and when you manipulate either, you're manipulating the direct instance, not a reference to it. I understand all of that, and I also know that you can use == on two ints. Why not on two structs then? Wouldn't you just go to the stack and compare them on a member-by-member basis?
I went around and asked a few folks. To protect the guilty, I will say that Coworker X saw my point, while Coworker Y decried us both as morons. "Ha ha," we cried haughtily, "we'll show him!" And so we promptly worked up a quick example, only to promptly be proven incorrect. I sank to my knees and cried at the heavens, "What the fudge?"
To complicate matters, structs inherit an Equals method from System.ValueType (I think) and that Equals method seems to work exactly as I thought the == operator would work. So what gives? Why does one work and not the other? Anyone, anyone? I am lost on this subject and I am in desperate need of guidance.
Good afternoon, gentlemen and gentleladies. Just recently, I started reading Steve McConnell's development classic, Code Complete. As I get farther and farther into it, I may start sharing a few of the tips enclosed in said development classic, but not today. Today, however, we have smaller fish to fry. Specifically, I'd like to share one method in C# and VB.NET that, while not exactly obscure, is worth covering because of its simplicity and ubiquity. Just how simple and ubiquitous is it? Well, it may not be the main topic of discussion down at the beauty parlor or the saloon, but it scratches an itch that always seems to appear in the course of programming business applications. In fact, it is so successful at scratching this itch, I think of it as computational calamine lotion. Okay, enough build-up; I'm actually talking about the Parse method.
Bajillions of times throughout programming history, someone has tried to parse a string for a numeric value. Bajillions of times, a five line function has been written that may or may not contain serious defects. That's one of the reasons why I like Parse so much; not only does it prevent a lot of code rewrite, but since it's part of the framework, you know the testers at Microsoft have devoted some serious time in attempting to break it.
Let's look at an example of how one makes use of this method. Let's say we're working on the business logic for a billing system. The billing system takes verbose orders (eg, "23,000 Catalytic Converters"), and we need to capture the quantity of the order from that information. How do we do that? Well, we place a collect call to the Parse method. Here's an idea of the code.
long firstOrderQuantity = Int64.Parse(firstOrder, System.Globalization.NumberStyles.Any);
//firstOrderQuantity is now 23000.
The larger point here is that you can parse all kinds of stuff. The Parse method is a static method on any numeric value type (short, double, decimal, etc), so you can do the exact same thing for all different types of numbers. You can also parse numbers into bytes, characters into their unicode equivalents, and lots of other cool stuff. If you're curious about all of the options, just take a look at the destination datatype's parse method: byte.Parse(), decimal.Parse(), and so forth.
Writing a method of your own to do all of this could be incredibly daunting, especially when one considers all of the formats in which a number can be inputted. It's not as hard as bench-pressing a dump truck, but I'd hesitate to call it easy. Luckily, Microsoft has made such a method available in the framework. For this, I invite Bill Gates and the CLR team to my house for a corny dog. Not one corny dog each, but one to be shared across all of them; I'm not made out of cornmeal, people.
I discovered something interesting today. Let's say you write a small app in C# or VB.NET to run in the background and perform some really important system service. Since it's important (maybe it polls the security cams to make sure no killer robots are on the premises), you want to know if this service ever goes down. Your idea is that this app will grab the administrator's email from a database, and then send her an email before it closes.
I spent a little bit of time today implementing something similar; being a total fancy lad when it comes to object-oriented programming, I figured I would just put the code in the destructor for my object. That way, when the app began to destroy my object as the application closed, the appropriate code would run. My idea was that it'd look something like this:
string from = "Polling Agent Application";
string subject = "I'm going down";
string message = "Sweet bearded Zeus, the end is near! Restart me ASAP!";
//then call a method to send this email. It's always a good idea
//to have one of these methods in your app, since users like email
//and it's a pain to rewrite.
this.SendEmail(from, adminEmail, subject, message);
}
Okay, so I planted that in my destructor and then tried it out, only to discover that the app made a mess in its pants whenever I tried to exit. Specifically, I got a "Handle is not initialized" exception, referring to the db method I call in the destructor. What's the dealio here? The code is sound; I played around for a bit and saw I could use that method in any other part of the program aside from the destructor and it'd work fine. Something is fishy here, and it ain't the tuna helper.
Well, a bit of research (and a really informative usenet post by David Browne) revealed that utilizing a SqlConnection in your destructor cannot work. This is because the final garbage collection tends to destroy objects in an indeterminate order, so your destructor may try to access an object that's already been destroyed. If you try to access a SqlConnection then, you may end up trying to use something that's being utilized by another thread entirely. That, as the Spaniards say, es muy mal. Rather than checking the state of all of these complicated objects, the CLR just limits what you can access in the destructor.
So, how can we do this? Well, what I ended up doing was making my adminEmail string a member of the class, and setting it to the proper value in my constructor. I could access that with no problems at all in destructor.
In conclusion, .NET's destructor presents a few hurdles to the developer; there's a lot of potential for functionality there, you just have to be very specific in the way you code. (I'd be interested in knowing whether Java is the same way, maybe I'll follow up on that a little later.) Luckily, the only type of pants we wear here on the vlog are our smarty pants.
A question for the C# UI developers (a stunningly handsome bunch, from my experience): have you ever tried to display a sequence of dialog forms? Maybe you have a series of back and forward buttons that the user can cycle through. It makes sense to display some things in such a manner, but it's really hard to code the sequence straight, particularly if the user can cancel during the middle. It's not quite as hard as tracking and killing the Sasquatch, but probably around hthe difficulty of karate chopping a car in half.
Anyway, here's a good method I came up with, relying heavily on collections of forms. It's important to set the DialogResult of each button correctly: Forward is DialogResult.OK, Back is DialogResult.Retry, and Cancel is DialogResult.Cancel.
//next, populate the arraylist with the proper order.
frmOne myFormOne = new frmOne();
frmTwo myFormTwo = new frmTwo();
forms.Add(myFormOne);
forms.Add(myFormTwo);
//show the first form.
ShowChildForm(0);
}
private void ShowChildForm(int ithForm)
{
//actually show the form.
DialogResult temp = ((Form)forms[ithForm]).ShowDialog();
//then parse the result from the form.
ParseNavigation(temp, (Form)forms[ithForm]);
}
private void ParseNavigation(DialogResult temp, System.Windows.Forms.Form referrer)
{
//we've abstracted the form navigation so that there are only
//three base actions: cancel, ok, and cancel.
switch(temp)
{
case(DialogResult.Cancel):
CancelFound(); //delete your records or whatever.
break;
case(DialogResult.OK): //OK means move on to the next.
PerformNavigation(referrer, true);
break;
case(DialogResult.Retry): //Retry means Go Back.
PerformNavigation(referrer, false);
break;
}
}
private void PerformNavigation(System.Windows.Forms.Form referrer, bool moveForward)
{
int moveSpots;
//loop through our arraylist of forms
for (int i = 0; i < forms.Count; i++)
{
Type formType = forms[i].GetType();
Type referrerType = referrer.GetType();
//if the referrer matches the form we're looking at,
//let's go to work.
if (formType == referrerType)
{
if (moveForward)
moveSpots = 1;
else
moveSpots = -1;
ShowChildForm(i+moveSpots);
}
}
}
Just a teensy little bit more about casting and converting with C#. Previously, we covered the relative strengths and weaknesses of both methods for converting types in C#. Now let's be honest here: after the last post, it was freaking impossible not to get swept away in a moment of fancy and think to yourself, "Maaan, it'd be great if there was some way to combine casting and converting!" And then, maybe you went overboard on the moment of fancy and thought, "If this software thing doesn't work out, I'm going to start up a diner full of Andy Griffin memorabilia! We'll get Don Knotts for the ribbon cutting!" Both thoughts are equally intriguing, but only one is appropriate for the vlog (my apologies to Mr. Knotts).
As savvy programmers, What'd we like is a method that combines the speed and ease of casting with the flexibility of converting. Luckily, the C# fairies sprinkled just enough pixiedust on the compiler to acommodate this, sort of. The magic word here is 'as'.
Let us code with the futzy old method! (Apologies to America's favorite portly funny man.)
string domCalories = (string) domDeLuiseBreakfast;
MessageBox.Show(domCalories);
}
catch(Exception ex)
{
MessageBox.Show("Oops! " + ex.Message);
}
Welcome to exception city, population you. We can get around this with a sneaky part of C#, the "as" keyword. Take a whiff of this.
//we're not casting, we're using the as keyword.
string domCalories = domDeLuiseBreakfast as string;
MessageBox.Show(domCalories);
}
catch(Exception ex)
{
MessageBox.Show("Oops! " + ex.Message);
}
So 'as' returns null for invalid casts, instead of throwing exceptions. Hoorah, we'll use that from now on and never again use cast or convert. Not so fast, hot shot. Let's alter our code sample slightly. domCalories is an int now instead of a string.
//no longer as string,now as Int16.
int domCalories = domDeLuiseBreakfast as Int16;
MessageBox.Show(domCalories.ToString());
}
catch(Exception ex)
{
MessageBox.Show("Oops! " + ex.Message);
}
Summing up the past couple of entries, we now have three separate cases for casting, using 'as', and converting.
Why it's so easy, you could teach it to a squirrel. It's possible to make it much more complicated than all of this, but our jobs are complicated enough already. For that reason, I'm a strong proponent for keeping it simple. With a few simple rules of thumb, you can tackle almost any variable conversion situation in C#. Not only that, but it gives you the valuable opportunity to give something back to the squirrel programmer population.
Here's a joke I just made up about casting. Yes, I am a horrendous nerd.
One day, an integer was walking down the street when he spied a man in a booth. Above the booth, a sign read, "I'll Make You a Long for $1!" Always wanting to be a float, the integer ran over to the man and gave him a big pile of money. In return, the man gave him a magic pill that he promised would turn the int to a long.
That night, the int took the magic pill. He immediately felt bigger, but he wasn't sure just how much bigger he was. He decided to test it out by assigning himself the lowest number he could think of, -3,000,000,000,000,000,000. Immediately when he tried, he broke to pieces. An ambulance came immediately and took him to the hospital, where only a team of sophisticated type surgeons could piece him back together.
The next day, the man who sold him the pill came to visit. Hysterical, the man said, "Oh God, it's all my fault! Is there anything I can do?" Cool as a cucumber, "Actually, yes. How about you sign my cast?"
HA HA HA HA, ohhhh my sides!
Now that we've identified what cast and convert are used for in C#, let's do a little detective work to determine how these two actually work. In doing detective work, it's always helpful to assume the persona of a famous private investigator, so imagine me typing all of this while dressed like Magnum PI.
The simplest way to illustrate the difference between casting and converting is with a code sample. Consider the following example of casting a string into an int, a hopeless task in this situation.
Let's review our results. We tried to do an invalid cast, and the compiler caught it, sending us back to our mommas. We tried to an invalid convert, and the compiler allowed it. Running the program then raised an exception that we were able to handle. From this, we can determine that casts are a lot stricter in what they'll handle than the comparatively lenient methods of the Convert class. In addition to that, a failed cast has a worse impact on the program than a failed convert.
What's the conclusion? Well, if casts are much stricter and more devastating upon failure, then we should only use them when we can guarantee success. Casts are only appropriate for data internal to the program, where validity can be ensured. Converts, being more flexible, are appropriate for other things where failure is a possibility, like handling input from a database or a user.
Unfortunately, casts are supposedly faster than converts (I'd like to see some numbers here), so we can't get rid of them entirely. Instead, we must eye them warily, like a farmer who's taken in a travelling salesman. Our user/db input is like our fetching daughter, who must be guarded zealously from this brute. If, in the dead of the night, we hear the salesman getting close to the daughter, it's our job to run towards the barn, screaming like holy hell and brandishing a pitchfork. A programmer's job is never done.
Okay, enough with pseudo-nerdery; it's time to get wonky. Specifically, I'd like to write today about the differences between casting and converting in C#. Developers (and Microsoft in the documentation) use these terms interchangeably, but they're quite different. Such confusion causes pedantic jerks around the world (like me) to hyperventilate and break out in hives. We must put our foot down regarding these concepts, and to borrow a quote from Animal House, that foot is me.
As a language, C# is strongly-typed. A lot of ambiguity surrounds this term, but basically it means all variables must be declared with a type, and each variable must adhere to its type. That last part just means that if you declare something as a string, you're not allowed to suddenly treat it like an integer and add 15 to it. As a result, strongly typed languages enforce consistency, and that's a good thing. Okay, most programmers know this already.
In almost any non-trivial program, a developer will encounter a situation where she needs to use the data from a variable in an altogether different context. For example, say you've declared a variable x as a double, and you're using x to track the number of dollars your department has spent on Garfield posters (trust me, any reasonable organization will need a double to track this amount). At the end of each week, you're supposed to tell your boss the grand total. However, she's not really interested in the complete amount; she just wants it rounded down to the nearest dollar. It's clear here that what you need to do is change that double, which tracks dollars and cents, to an int, which doesn't carry decimal places. How do we go about that in C#?
Well, maybe like this:
Casting and converting are the two main ways to change types of a variable (there are other methods too, and we'll get to them eventually). Casting looks like this: