Skip to content

Commit bd4b8a9

Browse files
Fix TODOs in concepts (#1571)
1 parent a750952 commit bd4b8a9

File tree

48 files changed

+501
-276
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+501
-276
lines changed

concepts/arrays/about.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# About
22

3-
TODO: about.md files and links.json files are the same for arrays, for-loops and foreach. Consider how to prise these apart of otherwise treat these closely coupled concepts.
43
Data structures that can hold zero or more elements are known as _collections_. An **array** is a collection that has a fixed size/length and whose elements must all be of the same type. Elements can be assigned to an array or retrieved from it using an index. C# arrays are zero-based, meaning that the first element's index is always zero:
54

65
```csharp
@@ -28,6 +27,8 @@ int[] threeIntsV3 = { 4, 9, 7 };
2827

2928
Arrays can be manipulated by either calling an array instance's [methods][array-methods] or [properties][array-properties], or by using the static methods defined in the [`Array` class][array-class].
3029

30+
## Iteration
31+
3132
An array is also a _collection_, which means that you can iterate over _all_ its values using a [`foreach` loop][foreach-statement]:
3233

3334
```csharp

concepts/bit-manipulation/about.md

Lines changed: 9 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,15 @@
11
# About
22

3-
TODO: See #2112. We need to reconsider the text below now that it is a stand alone concept or maybe bitwise manipulation should be introduced in a separate exercise and the flag-enums exercise and concept should take that as a dependency showing how bitwise manipulation is used in the context of enums.
3+
C# has several operators to do bitwise manipulation:
44

5-
To allow a single enum instance to represent multiple values (usually referred to as _flags_), one can annotate the enum with the `[Flags]` attribute. By carefully assigning the values of the enum members such that specific bits are set to `1`, bitwise operators can be used to set or unset flags.
5+
- [`&`][and-operator]: bitwise AND
6+
- [`|`][or-operator]: bitwise OR
7+
- [`~`][complement-operator]: bitwise COMPLEMENT
8+
- [`<<`][left-shift-operator]: bitwise shift left
9+
- [`>>`][right-shift-operator]: bitwise shift right
610

7-
```csharp
8-
[Flags]
9-
enum PhoneFeatures
10-
{
11-
Call = 1,
12-
Text = 2
13-
}
14-
```
15-
16-
Besides using regular integers to set the flag enum members' values, one can also use [binary literals or the bitwise shift operator][binary-literals].
17-
18-
```csharp
19-
[Flags]
20-
enum PhoneFeaturesBinary
21-
{
22-
Call = 0b00000001,
23-
Text = 0b00000010
24-
}
25-
26-
[Flags]
27-
enum PhoneFeaturesBitwiseShift
28-
{
29-
Call = 1 << 0,
30-
Text = 1 << 1
31-
}
32-
```
33-
34-
An enum member's value can refer to other enum members values:
35-
36-
```csharp
37-
[Flags]
38-
enum PhoneFeatures
39-
{
40-
Call = 0b00000001,
41-
Text = 0b00000010,
42-
All = Call | Text
43-
}
44-
```
45-
46-
Setting a flag can be done through the [bitwise OR operator][or-operator] (`|`) and unsetting a flag through a combination of the [bitwise AND operator][and-operator] (`&`) and the [bitwise complement operator][bitwise-complement-operator] (`~`). While checking for a flag can be done through the bitwise AND operator, one can also use the enum's [`HasFlag()` method][has-flag].
47-
48-
```csharp
49-
var features = PhoneFeatures.Call;
50-
51-
// Set the Text flag
52-
features = features | PhoneFeatures.Text;
53-
54-
features.HasFlag(PhoneFeatures.Call); // => true
55-
features.HasFlag(PhoneFeatures.Text); // => true
56-
57-
// Unset the Call flag
58-
features = features & ~PhoneFeatures.Call;
59-
60-
features.HasFlag(PhoneFeatures.Call); // => false
61-
features.HasFlag(PhoneFeatures.Text); // => true
62-
```
63-
64-
[docs.microsoft.com-enumeration-types-as-bit-flags]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/enumeration-types#enumeration-types-as-bit-flags
65-
[alanzucconi.com-enum-flags-and-bitwise-operators]: https://www.alanzucconi.com/2015/07/26/enum-flags-and-bitwise-operators/
6611
[or-operator]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#logical-or-operator-
6712
[and-operator]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#logical-and-operator-
68-
[bitwise-complement-operator]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#bitwise-complement-operator-
69-
[binary-literals]: https://riptutorial.com/csharp/example/6327/binary-literals
70-
[has-flag]: https://docs.microsoft.com/en-us/dotnet/api/system.enum.hasflag?view=netcore-3.1
13+
[complement-operator]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#bitwise-complement-operator-
14+
[left-shift-operator]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#left-shift-operator-
15+
[right-shift-operator]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#right-shift-operator-
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
# Introduction
22

3-
TODO: add introduction for bit-manipulation concept
3+
C# has several operators to do bitwise manipulation:
4+
5+
- `&`: bitwise AND
6+
- `|`: bitwise OR
7+
- `~`: bitwise COMPLEMENT
8+
- `<<`: bitwise shift left
9+
- `>>`: bitwise shift right

concepts/casting/about.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ The [C# documentation][type-testing-and-cast-operators] classifies type conversi
66

77
In C# very often, outside of the realm of numeric values and class hierarchies, you will have to make a conversion by calling some member of the "to" type such as [`Int32.Parse()`][int32-parse] which converts a string to an integer or by calling a member of the "from" type e.g. `object.ToString()`. Javascript and developers in other dynamic languages should be aware.
88

9-
Note that implicit an explicit cast [operators][operator-overloading] (discussed in (TODO cross-ref-tba)) are available which can bring fairly arbitrary casting to your own types.
9+
Note that implicit an explicit cast [operators][operator-overloading] (discussed in [concept:csharp/operator-overloading]()) are available which can bring fairly arbitrary casting to your own types.
1010

1111
## Casting Primitive Types - Implicit
1212

@@ -114,7 +114,7 @@ The [`as`][as-operator] keyword fulfills a similar function to `is` e.g. `var fo
114114

115115
## Custom Cast Operator
116116

117-
Types can define their own custom explicit and implicit [cast operators][custom-casts]. See (TODO cross-ref-tba) for coverage of this..
117+
Types can define their own custom explicit and implicit [cast operators][custom-casts].
118118

119119
Examples of [explicit][big-integer-explicit] and [implicit][big-integer-implicit] casts in the BCL is conversions from the `BigInteger` struct to and from other numeric types
120120

concepts/compound-assignment/about.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
# About
22

3-
TODO: See issue #2112. I think we need a different exercise to introduce compound assignments (one that shows it being used in a more conventional numeric or string context. flag-enums could then take that as a dependency and show how it is used in this more unusual context.
4-
5-
The bitwise operators can also be used as [compound assignments][compound-assignment], which are a shorthand notation where `x = op y` can be written as `x op= y`:
3+
Many operators can also be used as [compound assignments][compound-assignment], which are a shorthand notation where `x = op y` can be written as `x op= y`:
64

75
```csharp
86
var features = PhoneFeatures.Call;
@@ -11,4 +9,4 @@ features &= ~PhoneFeatures.Call;
119
```
1210

1311
[compound-assignment]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators#compound-assignment
14-
[compound-assignment-alt]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#compound-assignment
12+
[compound-assignment-alt]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#compound-assignment
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
# Introduction
22

3-
TODO: add introduction for compound-assignment concept
3+
Many operators can also be used as compound assignments, which are a shorthand notation where `x = op y` can be written as `x op= y`:
4+
5+
```csharp
6+
var features = PhoneFeatures.Call;
7+
features |= PhoneFeatures.Text;
8+
features &= ~PhoneFeatures.Call;
9+
```
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
{
22
"blurb": "A const allows you to specify fields where their value is known at compile time and will not change during the runtime of the program.",
3-
"authors": ["TODO: add author"],
4-
"contributors": [
5-
"yzAlvin"
6-
]
3+
"authors": ["erikschierboom"],
4+
"contributors": ["yzAlvin"]
75
}

concepts/const-readonly/about.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
11
# About
22

3-
TODO: add information on const-readonly concept
3+
By default, values in C# are _mutable_, that is they can change over time. To make a value _immutable_, there are two options:
4+
5+
1. Add the [`const` modifier](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const)
6+
2. Add the [`readonly` modifier](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/readonly#readonly-field-example)
7+
8+
The `const` modifier has some restrictions:
9+
10+
1. It can only be applied to "constant" types: strings, booleans and numbers.
11+
1. The `const` value must be initialized immediately.
12+
13+
See [definining constants](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/how-to-define-constants) for more information.
14+
15+
If your value is a non-constant type or you need to initialize the value in a constructor, `readonly` can be used to enforce immutability.
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
11
# Introduction
22

3-
TODO: add introduction for const-readonly concept
3+
By default, values in C# are _mutable_, that is they can change over time. To make a value _immutable_, there are two options:
4+
5+
1. Add the `const` modifier
6+
2. Add the `readonly` modifier
7+
8+
The `const` modifier has some restrictions:
9+
10+
1. It can only be applied to "constant" types: strings, booleans and numbers.
11+
1. The `const` value must be initialized immediately.
12+
13+
If your value is a non-constant type or you need to initialize the value in a constructor, `readonly` can be used to enforce immutability.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"blurb": "Enumerables are values that can be iterated over.",
3-
"authors": ["TODO: add author"],
3+
"authors": ["erikschierboom"],
44
"contributors": []
55
}

concepts/enumerables/about.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
11
# About
22

3-
TODO: complete document
3+
Types that implement the [`IEnumerable<T>`](https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.ienumerable-1?view=net-5.0) interface are known as being _enumerable_. All built-in collection types implement this interface.
4+
5+
An enumerable type can be iterated over using a `foreach` loop:
6+
7+
```csharp
8+
var primes = new[] { 2, 3, 5, 7 };
9+
foreach (var prime in primes)
10+
{
11+
Console.Write(prime);
12+
}
13+
// => 2357
14+
```
15+
16+
To implement `IEnumerable<T>`, a type has to implement one method: `IEnumerator<T> GetEnumerator()`. As seen, an enumerable defers the actual iterating over a collection to an `IEnumerator<T>` type. This interface has one property and three methods to implement:
17+
18+
- `public T Current { get; }`: get the current element.
19+
- `public bool MoveNext ();`: move to the next element, returning `true` if the move to the next element was successful, and `false` if not (no more elements).
20+
- `public void Reset ();`: reset the enumerator to its initial state (before the first element).

concepts/enumerables/introduction.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
11
# Introduction
22

3-
TODO: complete document
3+
Types that implement the `IEnumerable<T>` interface are known as being _enumerable_. All built-in collection types implement this interface.
4+
5+
An enumerable type can be iterated over using a `foreach` loop:
6+
7+
```csharp
8+
var primes = new[] { 2, 3, 5, 7 };
9+
foreach (var prime in primes)
10+
{
11+
Console.Write(prime);
12+
}
13+
// => 2357
14+
```
15+
16+
To implement `IEnumerable<T>`, a type has to implement one method: `IEnumerator<T> GetEnumerator()`. As seen, an enumerable defers the actual iterating over a collection to an `IEnumerator<T>` type. This interface has one property and three methods to implement:
17+
18+
- `public T Current { get; }`: get the current element.
19+
- `public bool MoveNext ();`: move to the next element, returning `true` if the move to the next element was successful, and `false` if not (no more elements).
20+
- `public void Reset ();`: reset the enumerator to its initial state (before the first element).

concepts/exception-filtering/about.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
# About
22

3-
TODO: This may need a more rounded introduction to filtering here.
43
`when` is the keyword in filtering exceptions. It is placed after the catch
54
statement and can take a boolean expression containing any values in scope at the time. They don't just have to be members of the exception itself. If the type of the exception matches and the expression evaluates to true then the block associated with that `catch` statement is executed otherwise the next `catch` statement, if any, is checked.
65

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"blurb": "When there is no built-in implicit conversion between two types, an explicit cast has to be used.",
3-
"authors": ["TODO: add author"],
3+
"authors": ["erikschierboom"],
44
"contributors": []
55
}

concepts/explicit-casts/about.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
11
# About
22

3-
TODO: add information on explicit-casts concept
3+
Where types cannot be cast implicitly, you must use an explicit cast [operator][cast-operator].
4+
The cast operator is nothing more than the target type in parentheses before the value you want to cast:
5+
6+
```csharp
7+
8+
int i = 7;
9+
byte b = (byte)i; // Explicit cast from int to byte
10+
```
11+
12+
Using an explicit cast is potentially dangerous. The two most common errors are:
13+
14+
- Casting to an incompatible type. This will throw an exception at runtime.
15+
- Casting to a numeric value that is insufficiently "wide". This can result in a sign conflict or an overflow exception being thrown in the case of integers
16+
17+
Note: an expression of type `int` can be explicitly cast to `char`. This may result in an invalid `char`.
18+
19+
[cast-operator]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast#cast-expression
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
# Introduction
22

3-
TODO: add introduction for explicit-casts concept
3+
Where types cannot be cast implicitly, you must use an explicit cast operator.
4+
The cast operator is nothing more than the target type in parentheses before the value you want to cast:
5+
6+
```csharp
7+
8+
int i = 7;
9+
byte b = (byte)i; // Explicit cast from int to byte
10+
```

concepts/for-loops/about.md

Lines changed: 11 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,26 @@
11
# About
22

3-
TODO: about.md files and links.json files are the same for arrays, for-loops and foreach. Consider how to prise these apart of otherwise treat these closely coupled concepts.
4-
Data structures that can hold zero or more elements are known as _collections_. An **array** is a collection that has a fixed size/length and whose elements must all be of the same type. Elements can be assigned to an array or retrieved from it using an index. C# arrays are zero-based, meaning that the first element's index is always zero:
3+
A [`for` loop][for-statement] allows one to repeatedly execute code in a loop until a condition is met.
54

65
```csharp
7-
// Declare array with explicit size (size is 2)
8-
int[] twoInts = new int[2];
9-
10-
// Assign second element by index
11-
twoInts[1] = 8;
12-
13-
// Retrieve the second element by index
14-
twoInts[1] == 8; // => true
15-
16-
// Check the length of the array
17-
twoInts.Length == 2; // => true
18-
```
19-
20-
Arrays can also be defined using a shortcut notation that allows you to both create the array and set its value. As the compiler can now tell how many elements the array will have, the length can be omitted:
21-
22-
```csharp
23-
// Three equivalent ways to declare and initialize an array (size is 3)
24-
int[] threeIntsV1 = new int[] { 4, 9, 7 };
25-
int[] threeIntsV2 = new[] { 4, 9, 7 };
26-
int[] threeIntsV3 = { 4, 9, 7 };
27-
```
28-
29-
Arrays can be manipulated by either calling an array instance's [methods][array-methods] or [properties][array-properties], or by using the static methods defined in the [`Array` class][array-class].
30-
31-
An array is also a _collection_, which means that you can iterate over _all_ its values using a [`foreach` loop][foreach-statement]:
32-
33-
```csharp
34-
char[] vowels = new [] { 'a', 'e', 'i', 'o', 'u' };
35-
36-
foreach (char vowel in vowels)
6+
for (int i = 0; i < 5; i++)
377
{
38-
// Output the vowel
39-
System.Console.Write(vowel);
8+
System.Console.Write(i);
409
}
4110

42-
// => aeiou
11+
// => 01234
4312
```
4413

45-
One could use a [`for` loop][for-statement] to iterate over an array:
46-
47-
```csharp
48-
char[] vowels = new [] { 'a', 'e', 'i', 'o', 'u' };
14+
A `for` loop consists of four parts:
4915

50-
for (int i = 0; i < vowels.Length; i++)
51-
{
52-
// Output the vowel
53-
System.Console.Write(vowels[i]);
54-
}
16+
1. The initializer: executed once before entering the loop. Usually used to define variables used within the loop.
17+
2. The condition: executed before each loop iteration. The loop continues to execute while this evaluates to `true`.
18+
3. The iterator: execute after each loop iteration. Usually used to modify (often: increment/decrement) the loop variable(s).
19+
4. The body: the code that gets executed each loop iteration.
5520

56-
// => aeiou
57-
```
21+
## for vs foreach loops
5822

59-
However, generally a `foreach` loop is preferrable over a `for` loop for the following reasons:
23+
In general [concept:csharp/foreach-loops]() are preferrable over `for` loops for the following reasons:
6024

6125
- A `foreach` loop is guaranteed to iterate over _all_ values. With a `for` loop, it is easy to miss elements, for example due to an off-by-one error.
6226
- A `foreach` loop is more _declarative_, your code is communicating _what_ you want it to do, instead of a `for` loop that communicates _how_ you want to do it.
@@ -83,13 +47,6 @@ A `for` loop does have some advantages over a `foreach` loop:
8347
- You can process collections from back to front by counting down.
8448
- You can use `for` loops in scenarios that don't involve collections.
8549

86-
Related Topics:
87-
88-
- You should be aware that C# supports [multi-dimensional arrays][multi-dimensional-arrays] like `int[,] arr = new int[10, 5]` which can be very useful.
89-
- You should also be aware that you can instantiate objects of type [`System.Array`][system-array-object] with `Array.CreateInstance`. Such objects are of little use - mainly for interop with VB.NET code. They are not interchangeable with standard arrays (`T[]`). They can have a non-zero lower bound.
90-
91-
Both the above topics are discussed more fully in a later exercise.
92-
9350
[implicitly-typed-arrays]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/implicitly-typed-arrays
9451
[array-foreach]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/using-foreach-with-arrays
9552
[single-dimensional-arrays]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/arrays/single-dimensional-arrays

0 commit comments

Comments
 (0)