Programming 2, Summer 2022
Week 2: Notes

This week we expanded our knowledge of C#: we learned about characters, strings, string interpolation, nullable types, the 'foreach' statement, and arrays. You can read about these topics in chapters 2-4 of Essential C#.

reading input

The Console.ReadLine() method reads a line of standard input. It returns a value of type 'string?', which is either a string, or is null (in the case that no more input is available). So we can write

string? s = Console.ReadLine();
if (s == null)
    Console.WriteLine("no more input");
else
    Console.WriteLine(s);

To keep things simple, often we don't want to worry about the null case. We can use the null-forgiving operator ! to convert from the nullable type 'string?' to the type 'string', which cannot be null:

string s = Console.ReadLine()!;

This operator is like an assertion that the value will not be null. (If it actually is null at run time, the program will fail with an exception.)

converting a string to an int

The function int.Parse() can convert a string to an integer.

So we can read an integer on a single line like this:

int i = int.Parse(Console.ReadLine()!);

writing a Main() function

When you create a C# program using 'dotnet new console', the program can contain top-level code, i.e. code that is not contained in any class or method. We have used this style of programming in our examples so far.

Alternatively, you can put your main code into a static function Main() inside a class. For example, here is a program that reads two integers, then prints their sum:

using static System.Console;

class Sum {
    static void Main() {
        int i = int.Parse(ReadLine()!);
        int j = int.Parse(ReadLine()!);
        WriteLine(i + j);
    }
}

Note that ReCodEx currently cannot accept top-level code, so you must write a wrapper class and Main() function if you plan to submit your program to ReCodEx.

implicit namespaces

Our library quick reference page shows that the classes in the C# library are organized into namespaces. As you can see in the section "Implicit namespaces" on that page, some namespaces including System are automatically available in a console program when you run it on your machine. However, these namespaces are not automatically available on ReCodEx, so you must import them a 'using' statement if you want your program to run successfully on ReCodEx.

For example, consider this program:

class Hello {
    static void Main() {
        Console.WriteLine("hello");
    }
}

If you create a console project on your machine and enter this code, it will work fine. However, this program will fail on ReCodEx because Console is in the System namespace, and the program has not imported that. To make the program work on ReCodEx, you need to add this 'using' statement at the beginning:

using System;

Alternatively, you can write 'using static System.Console' (as we did in the program above that adds two numbers):

using static System.Console;

class Hello {
    static void Main() {
        WriteLine("hello");
    }
}

(I personally find this more convenient, since I don't like to type 'Console.ReadLine' and 'Console.WriteLine' everywhere.)

If you want your project to require System and other common namespaces to be explicitly imported like on ReCodEx, you can disable implicit namespaces in your .csproj file:

<ImplicitUsings>disable</ImplicitUsings>