Table of Contents
- Chapter 2. C# Language Basics
- 2.1 A First C# Program
- 2.2 Syntax
- 2.3 Type Basics
- 2.4 Numeric Types
- 2.5 Boolean Type and Operators
- 2.6 Strings and Characters
- 2.7 Arrays
- 2.7.1 Default Element Initialization
- 2.7.2 Indices and Ranges
- 2.7.3 Multidimensional Arrays
- 2.7.4 Simplified Array Initialization Expressions
- 2.7.5 Bounds Checking
- 2.8 Variables and Parameters
- 2.9 Expressions and Operators
- 2.10 Null Operators
- 2.10.1 Null-Coalescing Operator
- 2.10.2 Null-Coalescing Assignment Operator
- 2.10.3 Null-Conditional Operator
- 2.11 Statements
- 2.12 Namespaces
Chapter 2. C# Language Basics
2.1 A First C# Program
2.2 Syntax
2.3 Type Basics
2.4 Numeric Types
2.5 Boolean Type and Operators
2.6 Strings and Characters
2.7 Arrays
Array = a fixed number of variables (i.e. elements) of a particular type
- elements in array always stored in a continuous block of memory. Hence, fast access
- declared using
type[] array_name
(square brackets after element type) - access element using
[i]
following 0-based index.
e.g. Declare an array
char[] vowels = new char[5];
Length of array:
Length
property of an array return number of elements in array- Array length cannot be changed after creation (memory is reserved)
- For more flexible data structure,
System.Collection
namespace provides more, like dynamically sized array, or dictionaries.
Array initialization expression declare and populate in single step:
char[] vowels = new char[] {'a','e','i','o','u'};
// or
char[] vowels = {'a', 'e', 'i', 'o', 'u'};
System.Array
class (detailed in Chap7):
- all arrays inherit from it
- This array class provides many methods, e.g. get, set elements
2.7.1 Default Element Initialization
Creating an array will preintialize the element with default values using 0s (i.e. bitwise 0ing the memory block)
int[] a = new int[1000];
Console.Write(a[123]); // 0
Values types versus reference types
Array itself is a reference type object.
- it can be
null
int[] a = null;
What happen when element is Value types or Reference type?:
- Value type: each element value is allocated as part of array (i.e. initialized by 0ing memory block)
- Reference type: element is allocated as null reference
- Solution: explicitly instantiate all elements after instantiating the array
// Element are value type
public struct Point { public int X, Y; }
Point[] a = new Point[1000];
int x = a[500].X;
// Element are reference type
public class Point { public int X, Y; }
Point[] a = new Point[1000];
int x = a[500].X; // Run-time error, NullReferenceException
// Solution: instantiate element after array instantiate
Point[] a = new Point[1000];
for (int i = 0; i < a.Length; i++ )
{
a[i] = new Point();
}
2.7.2 Indices and Ranges
Indcies & Ranges types (introduced in C#) simplify working with array elements
Indices
Index: refer element relative to the end of array using ^
^0
equals to length of array- C# implement indices using Index type
e.g. access element using index
char[] vowels = new char[] {'a','e','i','o','u'};
char lastElement = vowels[^1]; // 'u', last element
char secondToLast = vowels[^2]; // 'o'
// vowels[^0]; create error as out of index
e.g. Index type
Index first = 0;
Index last = ^1; // access last
char firstElement = vowels[first]; // 'a'
char lastElement = vowels[last]; // 'u'
Ranges
C# implement ranges using Range type to slice array using:
..
operator: from index a to index b^
operator: from the end
e.g. Use Range for slicing array
char[] firstTwo = vowels[..2]; // 'a', 'e'
char[] lastThree = vowels[2..]; // 'i', 'o', 'u'
char[] middleOne = vowels[2..3]; // 'i'
char[] lastTwo = vowels[^2..]; // 'o', 'u'
e.g. Range type
Range firstTwoRange = 0..2;
char[] firstTwo = vowels[firstTwoRange];
2.7.3 Multidimensional Arrays
2 varieties of multidimensional array:
- Rectangular (长方形): a n-dimensional block of memory
- jagged (锯齿状): arrays of arrays (each element array may not be the same size)
Rectangular arrays
- Declaring array using commas to separate dimension in square bracket
int[3,3]
.GetLength()
return length for given dimension (e.g..GetLength(0)
for dimension 0)
e.g. declaring array
int[,] matrix = new int[3,3];
e.g. get dimension
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
matrix[i,j] = i * 3 + j;
}
}
Jagged arrays
- Declare jagged array using successive square bracket for each dimension
int[3][]
- Inner dimension aren't specified, as inner array can be an arbitrary length.
- Each inner array is implicitly initialized to
null
. Hence, need mannually create each inner array via for loop or explicit initialization
// Declaration
int[][] matrix = new int[3][];
// Create inner array in matrix
for (int i = 0; i < matrix.Length; i++ )
{
matrix[i] = new int[3]; // Create inner array
for (int j = 0; j < matrix[i].Length; j++)
{
matrix[i][j] = i * 3 + j;
}
}
e.g. explicit array initialization
int[][] matrix = new int[][]
{
new int[] {0,1,2},
new int[] {3,4,5},
new int[] {6,7,8,9}
};
2.7.4 Simplified Array Initialization Expressions
Full array initialization is shown as e.g. above. Two ways of shorten array initialization expression
- Method 1: Omit
new
and type qualification - Method 2: use
var
to let compiler deduct type- Can be further simplified by omit type qualifier after
new
and have compiler infer the array type
- Can be further simplified by omit type qualifier after
e.g. method 1
char[] vowels = {'a', 'e', 'i', 'o', 'u'};
int[,] rectangularMatrix =
{
{0,1,2},
{3,4,5},
{6,7,8}
};
int[][] jaggedMatrix = {
new int[] {0,1,2},
new int[] {3,4,5},
new int[] {6,7,8,9}
};
e.g. method 2
var i = 3;
var s = "sausage"; // implicitly type string
var rectMatrix = new int[,]
{
{0,1,2},
{3,4,5},
{6,7,8}
};
var jaggedMat = new int[][]
{
new int[] {0,1,2},
new int[] {3,4,5},
new int[] {6,7,8,9}
}
// Further simplified
var vowels = new[] {'a','e','i','o'};
2.7.5 Bounds Checking
IndexOutOfRangeException
will be thrown if use invalid index, as all array indexing is bounds checked by the runtime.
int[] arr = new int[3];
arr[3] = 1; // IndexOutOfRangeException thrown
2.8 Variables and Parameters
2.9 Expressions and Operators
2.10 Null Operators
C# provides 3 operators to work with null:
- null-coalescing operator:
??
; - null-coalecing assignment operator (introduced in C# 8):
??=
; - null-conditional operator:
?.
;
2.10.1 Null-Coalescing Operator
??
: Means "If the operand to the left is non-null, give it to me; otherwise, give me another value"
string s1 = null;
string s2 = s1 ?? "nothing";
2.10.2 Null-Coalescing Assignment Operator
?=
: Means "If the operand to the left is null, assign the right operand to the left
if (myVariable == null) myVariable = someDefault;
2.10.3 Null-Conditional Operator
?.
is the null-conditional
or Elvis operator: Allows developer to call methods and access members just like the standard dot operator except that if the operand on the left is null, instead get NullReferenceException
- Useful in implementing lazy evaluation
- Elvis can be repeated
System.Text.StringBuilder sb = null;
string s = sb?.ToString(); // No error, instead of evaluating to null
// Same as
string s = (sb == null ? null : sb.ToString());
System.Text.StringBuilder sb = null;
string s = sb?.ToString().ToUpper(); // evaluates to null without error
// Repeated use of Elvis
x?.y?.z
// Same as
x == null ? null : (x.y == null ? null : x.y.z)
TODO: Summary not finished, will come back after nullable value type in chap4