C# Basics
C# is a general-purpose, type-safe, object-oriented programming language. Now it is also open source.
C# Basic Syntax (PART I)
Hello, world! Example
Console.WriteLine()
The Console.WriteLine() method is used to print text to the console.
Console.WriteLine("Hello, world!");
string myName = "Yun";
Console.WriteLine($"Hello, world! {myName}!"); // {} allows you to
// add variable in the string.
Console.ReadLine()
The Console.ReadLine() method is used to get user input.
Console.WriteLine("Enter your name: ");
string? name = Console.ReadLine(); // The ? symbol makes the name variable nullable
Data Types and Variables
C# is a type-safe language. When variables are declared it is necessary to define their data type. Types are categorized as Value or Reference by definition, but not its usage.
int (integer)
int a = 5;
bool (boolean)
bool b = true;
string (text)
string myName = "FirstName FamilyName";
float, double, and decimal (real number)
The type of a real literal is determined by its suffix: The literal without suffix or with the d or D suffix is of type double. The literal with the f or F suffix is of type float. The literal with the m or M suffix is of type decimal.
Console.WriteLine("Using doubles:");
double a = 0.1;
double b = 0.2;
if (a + b == 0.3)
{
Console.WriteLine($"{a} + {b} equals to 0.3");
}
else
{
Console.WriteLine($"{a} + {b} does NOT equal to 0.3");
}
What is the difference between these two code pieces?
Console.WriteLine("Using decimals:");
decimal c = 0.1M; // M suffix means a decimal literal value
decimal d = 0.2M;
if (c + d == 0.3M)
{
Console.WriteLine($"{c} + {d} equals to 0.3");
}
else
{
Console.WriteLine($"{c} + {d} does NOT equal to 0.3");
}
Using array to Store Multiple Variables
// Declare an integer array of length 3 without setting the values.
int[] integers = new int[3];
// `numbers` array that stores 3 integers
int[] numbers = { 3, 14, 59 };
// 'characters' array that stores 3 strings
string[] characters = new string[] { "Nana", "Coffee", "Kiwi" };
// 2D array
int[,] twoDArray = new int[4, 2];
var
var a = 1+2;
var subTotal = 0.2;
var salesTax = 0.1;
var totalPrice = subTotal + salesTax; // ambigious, can be float, double, or decimal, so which one is it here?
// based on the types of subTotal and salesTax.
if (totalPrice == 0.3)
{
Console.WriteLine($"{subTotal}+{salesTax} equal to 0.3.");
}
else
{
Console.WriteLine($"{subTotal}+{salesTax} does NOT equal to " + (subTotal + salesTax));
Console.WriteLine($"{subTotal}+{salesTax} does NOT equal to 0.3.");
}
Best practices for var
✅ Use var when it improves readability, especially with long type names:
var customers = new Dictionary<int, List<string>>();
✅ Use var in foreach loops:
foreach (var item in myList)
{
Console.WriteLine(item);
}
❌ Avoid var for simple types (like int, string, bool):
var age = 25; // Bad
int age = 25; // Better
❌ Avoid var when the type is not obvious:
var result = ProcessData(); // What does this return?
null value
int myNum = 4;
int? yourNum = null; // yourNum can be empty.
enum
// A self-defined type that contains ten cat types
enum WorldCatTypes
{
Polydactyl,
Snowshoe,
Calico,
BritishShorthair,
Siamese,
NorwegianForestCat,
JapaneseBobtail,
Persian,
ScottishFold,
GrayTabby
}
Using Operators (Symbolic Version of Methods)
Equality Operators
int a = 5;
int b = 10;
Console.WriteLine(a == b); // Return and print "false" because a is not equal to b.
Arithmetic Operators
int result = 0; // initialization
result = 10 + 5; // addition operator
result = 10 - 5; // subtraction operator
result = 10 * 5; // multiplication operator
result = 10 / 5; // division operator
result = 10 % 5; // modulo operator (returns the remainder)
Unary Operators
int a = 10;
a++; // a = a+1
a--; // a = a-1
++a; // What is the difference?
--a;
int a = 10;
int b = 0;
b = a++; // a = a+1
Console.WriteLine(a + ", " + b);
b = a--; // a = a-1
Console.WriteLine(a + ", " + b);
b = ++a;
Console.WriteLine(a + ", " + b);
b = --a;
Console.WriteLine(a + ", " + b);
Logical Operators Doc
bool b = false || true; // true;
Comparison/Relational Operators
string f = "first";
Console.WriteLine(f == "first");
int x = 10;
Console.WriteLine(x < 15); // Return and print "true" because 10 is less than 15.
Console.WriteLine(x < 5); // Return and print "false" because 10 is larger than 5.
Bitwise Operators Doc
uint a = 0b_1010_0000; // 0b tells the compiler that a is a binary literal
uint b = 0b_1001_0001; // _ is used as a digit separator.
// 0b_1010_0000 is equal to 0b10100000, just easier to read.
uint c = a | b;
Console.WriteLine(Convert.ToString(c, toBase: 2));
// Output:
// 10110001
Conditional Control (Selection)
if Statements / if and else / if and ilse if
int num = 10;
// if statement
if (num == 10)
{
Console.WriteLine("Yes, the num is 10.");
}
// if and else statement
if (num == 10)
{
Console.WriteLine("Yes, the num is 10.");
}
else
{
Console.WriteLine("No, the num is not 10.");
}
// if and else if statement
if (num == 10)
{
Console.WriteLine("Yes, the num is 10.");
}
else if (num == 20)
{
Console.WriteLine("Yes, the num is 20.");
}
else
{
Console.WriteLine("No, the num is neither 10 nor 20.");
}
switch
int num = 2;
void DisplayNum(double num)
{
switch (num)
{
case 1:
Console.WriteLine("1");
break;
case 2:
Console.WriteLine("2");
break;
case 3:
case 4:
Console.WriteLine("3 or 4");
break;
case 5:
goto case 1; // jump, usually not preferred
default: // Usually for debug purpose.
Console.WriteLine($"The num is {num}.");
break;
}
}
Conditional Control (Repetition/Iteration)
while
while (x > 5)
{
// Do something here.
}
do
do
{
// Do something here at least once.
} while (x > 5);
for
// for( initializer; condition; iterator )
for(int i = 0; i < 10; i++)
{
// Do something here.
Console.WriteLine(i);
}
int[] numbers = { 3, 14, 59 };
for(int i = 0; i < numbers.Length; i++)
{
// Do something here.
Console.WriteLine(numbers[i]);
}
foreach
var fibNumbers = new List<int> { 0, 1, 1, 2, 3, 5, 8, 13 };
foreach (int element in fibNumbers)
{
Console.Write($"{element} ");
}
// Output:
// 0 1 1 2 3 5 8 13
Main args()
//Simple calculator showing the use of args(), switch, and loops
using System;
class Program
{
static void Main(string[] args)
{
if (args.Length < 2)
{
Console.WriteLine("Usage: dotnet run -[operation] numbers...");
Console.WriteLine("Operations:");
Console.WriteLine(" -mul x y z... (Multiply numbers)");
Console.WriteLine(" -sum x y z... (Add numbers)");
Console.WriteLine(" -div x y (Divide x by y)");
Console.WriteLine(" -sub x y (Subtract y from x)");
return;
}
string operation = args[0];
double[] numbers = new double[args.Length - 1];
// Convert input strings to numbers manually
for (int i = 1; i < args.Length; i++)
{
if (!double.TryParse(args[i], out numbers[i - 1]))
{
Console.WriteLine($"Error: '{args[i]}' is not a valid number.");
return;
}
}
double result = 0;
switch (operation)
{
case "-mul":
result = 1; // Start with 1 for multiplication
for (int i = 0; i < numbers.Length; i++)
{
result *= numbers[i];
}
Console.WriteLine($"Result: {result}");
break;
case "-sum":
result = 0; // Start with 0 for addition
for (int i = 0; i < numbers.Length; i++)
{
result += numbers[i];
}
Console.WriteLine($"Result: {result}");
break;
case "-div":
if (numbers.Length != 2)
{
Console.WriteLine("Error: Division requires exactly two numbers.");
return;
}
if (numbers[1] == 0)
{
Console.WriteLine("Error: Division by zero is not allowed.");
return;
}
result = numbers[0] / numbers[1];
Console.WriteLine($"Result: {result}");
break;
case "-sub":
if (numbers.Length != 2)
{
Console.WriteLine("Error: Subtraction requires exactly two numbers.");
return;
}
result = numbers[0] - numbers[1];
Console.WriteLine($"Result: {result}");
break;
default:
Console.WriteLine("Error: Unknown operation. Use -mul, -sum, -div, or -sub.");
break;
}
}
}
C# Jump Statements Doc
Collatz Conjecture as an example
using System;
namespace CollatzConjecture
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please input a positive number:");
int? num = Int32.Parse(Console.ReadLine());
if (num == null || num <= 0)
{
Console.WriteLine("Sorry, the number should be larger than 1!");
return;
}
int steps = 0;
while (num != 1)
{
steps += 1;
if (num % 2 == 0)
{
num = num / 2;
}
else
{
num = num * 3 + 1;
}
}
if (num == 1)
{
Console.WriteLine($"Oh yeah, we reach 1 with {steps} steps!");
}
}
}
}
C# Basic Syntax (PART II)
Using Methods
A method is a code block that contains a series of statements.
In C#, a method declaration includes OptionalModifier ReturnType TheMethodName( ParameterType parameterName ) Also note that return only takes one parameter.
Variables Inside Methods (The Scope of Methods)
Parameters and variables declared inside of a method can be only used under the scope of the method. Return type should be matched. A method can have optional parameters
using System;
namespace CRC_CSD_03; // File scoped namespaces
class Program
{
static void Main(string[] args)
{
// Any of the following are valid method calls.
AddSomeNumbers(1); // Returns 6.
AddSomeNumbers(1, 1); // Returns 4.
AddSomeNumbers(3, 3, 3); // Returns 9.
int value = 0;
if (args.Length == 0)
{
Console.WriteLine($"The value is {value}.");
}
else if (args.Length == 1)
{
// int.Parse is a system method: Convert string to int
value = AddSomeNumbers(int.Parse(args[0]));
Console.WriteLine($"The value is {value}.");
}
else if (args.Length == 2)
{
value = AddSomeNumbers(int.Parse(args[0]), int.Parse(args[1]));
Console.WriteLine($"The value is {value}.");
}
else
{
value = AddSomeNumbers(int.Parse(args[0]), int.Parse(args[1]), int.Parse(args[2]));
Console.WriteLine($"The value is {value}.");
}
// a = 10; // compile error! The scope for a is not correct!
PrintMyName("Yun");
}
/*
Main: The class of my main program, where the application begins.
Input:
x: int
y: int, optional
z: int, optional
Output:
int
*/
static int AddSomeNumbers(int x, int y = 3, int z = 2)
{
int a = 5;
// return int
return x + y + z + a;
}
// return void, nothing to return
static void PrintMyName(string myName)
{
Console.WriteLine($"My name is {myName}.");
}
}
System Methods
Math.Sqrt() is a Math class method to calculate the square root of a value. “.” operator allows us to access a method of a class.
Console.WriteLine(Math.Sqrt(9));
$ 3
Call by Value vs. Call by Reference
Passing parameters in a method can be done by deep copying or referencing.
using System;
namespace CRC_CSD_03
{
class Program
{
static void Main(string[] args)
{
int number = 4;
SquareVal(number);
Console.WriteLine(number);
// Output: 4
SquareRef(ref number);
Console.WriteLine(number);
// Output: 16
}
/*
SquareVal: square a number.
Input:
num: int
Output:
none
*/
static void SquareVal(int num)
{
num *= num; // num = num * num
}
/*
SquareVal: square a number.
Input:
num: ref int
Output:
none
*/
static void SquareRef(ref int num)
{
num *= num; // num = num * num
}
}
}
$ 4
$ 16
Selected Theory
Recursion vs. Iteration
Factorial of a Given Number can be implemented using Recursion or Iteration.
using System;
namespace CRC_CSD_03
{
class Program
{
static void Main(string[] args)
{
int num = 5;
Console.WriteLine("Factorial of " + num +
" using Recursion is: " +
FactorialUsingRecursion(num));
Console.WriteLine("Factorial of " + num +
" using Iteration is: " +
FactorialUsingIteration(num));
}
/*
FactorialUsingRecursion: find factorial of given number using recurrsion.
Input:
num: int
Output:
int
*/
static int FactorialUsingRecursion(int n)
{
if (n == 1)
return 1;
// recursion call
return n * FactorialUsingRecursion(n - 1);
}
/*
FactorialUsingIteration: find factorial of given number using iteration.
Input:
num: int
Output:
int
*/
static int FactorialUsingIteration(int n)
{
int res = 1;
// using iteration
for (int i = 2; i <= n; i++)
{
res *= i;
}
return res;
}
}
}
$ Factorial of 5 using Recursion is: 120
$ Factorial of 5 using Iteration is: 120
Fibonacci Sequence can be implemented using Recursion or Iteration.
using System;
namespace CRC_CSD_03
{
class Program
{
static void Main(string[] args)
{
// initialization
int num = 5;
int[] sequence = new int[num];
// Calculate and print out the Fibonacci Sequence
// Recurrsion
resetFibonacciSequence(sequence);
Console.Write("A Fibonacci Sequence of elements " + num +
" using Recursion is: ");
FibonacciUsingRecursion(num, sequence);
printFibonacciSequence(sequence);
// Iteration
resetFibonacciSequence(sequence);
Console.Write("A Fibonacci Sequence of elements " + num +
" using Iteration is: ");
FibonacciUsingIteration(num, sequence);
printFibonacciSequence(sequence);
}
/*
resetFibonacciSequence: reset the sequence
Input:
sequence: int[]
Output:
none
*/
static void resetFibonacciSequence(int[] sequence)
{
for (int i = 0; i < sequence.Length; i++)
{
sequence[i] = -1;
}
}
/*
printFibonacciSequence: print the sequence
Input:
sequence: int[]
Output:
none
*/
static void printFibonacciSequence(int[] sequence)
{
for (int i = 0; i < sequence.Length; i++)
{
Console.Write(sequence[i] + " ");
}
Console.WriteLine("");
}
/*
FibonacciUsingRecursion: find the Fibonacci sequence of a given element
number using recurrsion.
Input:
num: int
sequence: int[]
Output:
int
*/
static int FibonacciUsingRecursion(int num, int[] sequence)
{
if (num == 1)
{
sequence[0] = 0;
return 0;
}
else if (num == 2)
{
sequence[0] = 0;
sequence[1] = 1;
return 1;
}
else
{
// recursion call
int value = FibonacciUsingRecursion(num - 2, sequence)
+ FibonacciUsingRecursion(num - 1, sequence);
sequence[num - 1] = value;
return value;
}
}
/*
FibonacciUsingIteration: find the Fibonacci sequence of a given element
number using iteration.
Input:
num: int
sequence: int[]
Output:
none
*/
static void FibonacciUsingIteration(int num, int[] sequence)
{
if (num == 1)
{
sequence[0] = 0;
return;
}
else if (num == 2)
{
sequence[0] = 0;
sequence[1] = 1;
return;
}
else
{
sequence[0] = 0;
sequence[1] = 1;
// using iteration
for (int i = 2; i < num; i++)
{
sequence[i] = sequence[i - 2] + sequence[i - 1];
}
}
}
}
}
$ A Fibonacci Sequence of elements 5 using Recursion is: 0 1 1 2 3
$ A Fibonacci Sequence of elements 5 using Iteration is: 0 1 1 2 3