Lab 3: Firing Events

In this lab we will focus on:

  • Methods (the "idea" behind methods and how we see them in console programs)
  • Signatures (parameters and return types; some bad examples)
  • Event Methods (how methods are used in GUI programming to make "triggerable" logic)

This lab will be due Sunday, Mar. 4th, midnight eastern time.

Methods

As you may recall from CIT 120, methods are also sometimes called functions or subroutines, and they are what allow us to create "reusable" logic. What do we mean by "reusable"?

Consider the following example:

public class Program
{
    public static void Main(string[] args)
    {
        Console.WriteLine("What is your age?");
        int age = Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("What is your shoe size?");
        int shoe = Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("What is your birth year?");
        int year = Convert.ToInt32(Console.ReadLine());

        Console.WriteLine("What is your favorite number?");
        int number = Convert.ToInt32(Console.ReadLine());
    }
}

Above, we have to repeat the same pattern of logic four times. We can save ourselves some time if we make this pattern itself "reusable" like so:

public class Program
{
    public static int Ask(string message)
    {
        Console.WriteLine(message);
        int result = Convert.ToInt32(Console.ReadLine());
        return result;
    }

    public static void Main(string[] args)
    {
        int age = Ask("What is your age?");
        int shoe = Ask("What is your shoe size?");
        int year = Ask("What is your birth year?");
        int number = Ask("What is your favorite number?");
    }
}

Here we've taken the parts of the logic that we were repeating, placed them in a method named Ask, and then used it to rewrite our Main in only four lines of code.

In general, there are two types of methods: value methods and void methods. Value methods compute something, a value, that we will want somewhere else in our code. For example, the Ask method "computes" a number by talking to the user.

Void methods, in contrast, do something. Although they might compute something for themselves to help complete whatever that task is, they aren't returning that value for us to use elsewhere. For example, Console.WriteLine is a void method, because it's only job is to do something, and that is print something to the screen. It doesn't make sense for this method to return to us with any particular value.

Signatures

Methods in C# are most similar to those in Java in terms of how they are written. That first line of the method is what we call the "signature" or "contract". For example, these lines from above:

public static int Ask(string message)
public static void Main(string[] args)

Each word of this contract specifies the "rules" for how this method will work.

The word public means that any logic anywhere else in any other file of the program is allowed to access this method. We could also use the word private here, to mean that only logic within this one file can access this method.

The word static means that we do not need to "create an instance" of an object to use this method. The Main is always static.

If something is "non-static," we just don't write the word static here. An example of a non-static method might be the block of logic that specifies how Dogs eat:

Dog molly = new Dog();
molly.Eat();

Here, we are writing molly.Eat(), not Dog.Eat(), and we had to create the variable molly first to use it. Compare this to how we do Console.WriteLine(). We don't need to "create" a copy of the console object first, so, this method is static.

Next, the words int and void specify the return type of the method. The Main is a void method, so we just put void here. But Ask is a value method, so we specify what type the return value will be.

Finally, inside the parentheses, we specify the arguments of the methods. In effect, the contract of the Ask method says, "If you give me a string, which I will refer to as message, then I will give you some int value." Similarly, the contract of the Main says, "I require an array of strings to do anything, which I'll call args." (This array of strings is given to the program when it is run from the command line, something we won't worry about in this class, but something that you-as-a-programmer must write your program to be ready for.)

Consider the following lines of code:

string answer = Ask("What is your name?");
int age = Ask();
int shoe = Ask("What is", "your shoe size?");

All three of these will fail.

The first does not work because Ask returns a number, yet we are trying to store it in a string variable. The second does not work because Ask requires a message to display. And the third does not work because Ask requires only and exactly a single string variable, yet we've tried to give it two (separated by commas) here.

Consider this example too:

public static void Repeat(string message, int times)
{
    // display the message so many times
    for (int i=0; i < times; ++i)
    {
        Console.WriteLine(message);
    }
}

This method does not return a value, since we specified it as void. Also, it requires a string and an int input, in that order. This means we can't do:

Repeat(5, "Hello World!");

The types and the order of the arguments we pass to methods must correspond properly, else we will get an error message when we try to compile.

The reason for this "strictness" is that, by adhering to contracts in this manner, the compiler can attempt to catch several common programmer errors for us. If we type the wrong method name by mistake, for example, odds are we'll be giving it the arguments intended for another method, and those arguments likely won't line up with the typoed method's contract.

Event Methods

Another advantage that we get from C#'s methods is an easy way to set up "events." When you are creating a GUI in Visual Studio, and you double click a button that you've added to the interface, then Visual Studio should create a "method stub" (a method with the contract filled out and a place for you to type the logic). This method, then, would be called whenever the "event" for that button is fired.

Event-Driven Programming is different from our console programs like this: in a console program, you can trace the order that the lines will run, from top to bottom; in a GUI-based program however, there are blocks of code that will run when the user interacts with that interface in a particular way. Therefore, we can't predict the order that our lines of code will run! Instead, we can prepare lines of code to respond to those various kinds of interface events.

This video (~6 minutes) demonstrates how to add event methods to buttons in Visual Studio:

C# _ How to add Events to Buttons _ Visual Studio 2015

And here is one more specific to WPF that talks a little about the "XAML" code at the bottom of the window:

Tutorial WPF Application (C#) - Event Handling

In either case, if you have a button named, for example, PremiumGasButton, you end up with a method like so:

private void PremiumGasButton_Click(object sender, RoutedEventArgs e)
{
    // put some logic here about how the user clicked
    // the premium gas option, so we're gonna charge
    // them a lot of money
}

Here, we see that Visual Studio has created an event method for us that is:

  • Private, so it can only be accessed by the logic of this particular window (good idea)
  • Non-static, so if we had another copy of this window (with its own copy of the premium gas button), then we'll have a copy of this logic specific to each premium gas button
  • Void, so when the user clicks a button, that event calls a doing kind of method, not a calculating kind of method (makes sense)
  • Takes two arguments, which, for us in this class, we can ignore. Just like how string[] args has to be there for the Main so it can "catch" the information comming from the command line, our event methods have to have two arguments, an "object" and a "RoutedEventArgs" so they can get information about how the event was fired.

Grading and Submission Instructions

To submit, write your responses to the following questions in a Word document, then upload it to Blackboard under this week's folder in Current Assignments.

Labs are due two weeks from when they are assigned, on Sunday at 11:59pm eastern time.

Labs are each worth 5% of your final grade. Scoring on your submission will be based on the following rubric:

0% - Student does not submit on time or submits plagiarized or unacceptable work. Double check that you have attached the right file, as usually students get zeros because they upload a previous week's Lab by accident.

1% - Student answers less than half of the questions with sufficient or accurate responses. Make sure that you are leaving yourself enough time to complete the Lab each week, as usually students submit incomplete work because they were rushed at the last minute.

3% - Student answers almost all questions with sufficient and accurate responses. If you encounter a problem or have a question about one of the questions, be sure to post in Ask the Instructor well before 24 hours before the due date, then continue to attempt to resolve the issue on your own while you wait for a reply.

5% - Great job, maximum points! The student answers all questions accurately and sufficiently, demonstrating the best of their ability.

Note, because Labs span two weeks' worth of reading, it is recommended to go through the Lab twice, once after the first reading where you answer everything that you can, then again after the second reading where you answer everything else.

Part 1

  1. In C#, which of the following is optional for a method: (a) a return type, (b) a parameter list, (c) body logic, or (d) an open and a close curly brace?
  2. If you want to create a method that other methods can access without limitations, you declare the method to be ___.
  3. Describe, according to the book, what the params keyword means in C#.
  4. Describe, according to the book, the concept of "ambigious" methods.
  5. What is the difference between a reference parameter and an output parameter?
  6. Is the method described by the following signature a value or a void method? public static int DoNothing(int x)
  7. I want to write a method that will accept a message parameter and will print that message in reverse. Is it better to code this as a void or a value method, and if you choose value method, what is the value that we should return? what data type is that value?

Part 2

  1. When you call a method (like Console.WriteLine) you do not need to know how it operates internally. Why?
  2. Assume we have a method with the following signature: public static void DoubleAndPrint(int num). Which of the following are illegal calls to this method, and why? (Hint: exactly two of these have errors)
    • DoubleAndPrint(int 55)
    • DoubleAndPrint(age)
    • DoubleAndPrint("55")
    • DoubleAndPrint(5 + 5)
  3. Research as necessary. What is the difference between "pass by value" and "pass by reference"? (Cite any sources you found useful in answering this question.)
  4. In C#, is an array passed by value or passed by reference?

Part 3

  1. Create a Console program that defines three "ask" methods similar to the one described in the lecture notes above: a RealNumberAsk that asks the user for a real number (a double); a WholeNumberAsk that asks the user for a whole number (an int); and a TextAsk that asks the user for text (a string). Then, in your Main, use these methods to ask the user for these values, making sure to use the appropriate method and type for each:
    • name
    • age
    • height
    • gpa
    • year of birth
    • make of their car (like Ford)
    • model of their car (like Taurus)
    • year of their car (like 2000)
  2. Create a GUI program that has three buttons: a Regular Unleaded button, a Plus Unleaded button, and a Premium Unleaded button. When the user clicks the Regular Unleaded button, the program should display a message with the current price for regular gas. You could use MessageBox.Show("The current price for regular unleaded gas is ___.") to do this. Similarly, the Plus Unleaded and Premium Unleaded buttons should display the current price for plus and premium gas.

If you are unable to complete any of the above programs by the due date, then submit screenshots of what you have, along with a description of any difficulties preventing your progress and a few ideas of what you could do to pass those roadblocks next time. (In other words, never leave an answer blank.)