Skip to content

Commit db4b1bc

Browse files
committed
Updated notes on CList as ICollection.
1 parent d5cb445 commit db4b1bc

5 files changed

Lines changed: 83 additions & 59 deletions

File tree

source/Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,9 @@ PANDOC_OPTIONS_ALT = $(PANDOC_OPTIONS) --lua-filter $(FIL_TEMPLATES)default-code
232232
PANDOC_HTM = $(PANDOC_OPTIONS_ALT) --toc --default-image-extension=svg --standalone --template=$(HTM_TEMPLATES)template.html --metadata title="ℙrinciples of ℂomputer ℙrogramming"
233233

234234
# PDF build options
235-
PANDOC_PDF:= $(PANDOC_OPTIONS_ALT) --toc --default-image-extension=svg --pdf-engine=xelatex --include-in-header=$(PDF_TEMPLATES)header.tex -V pdfstandard=ua-2
235+
PANDOC_PDF:= $(PANDOC_OPTIONS_ALT) --toc --default-image-extension=svg --pdf-engine=xelatex --include-in-header=$(PDF_TEMPLATES)header.tex
236+
# -V pdfstandard=ua-2
237+
# ! Package tagpdf Error: there is no open structure on the stack
236238

237239
# ODT build options
238240
PANDOC_ODT:= $(PANDOC_OPTIONS_ALT) --default-image-extension=png --reference-doc=$(ODT_TEMPLATES)custom-reference.odt
@@ -342,7 +344,8 @@ CLEAN-PREREQ:
342344
# && echo "](./$(basename $<).svg)" >> $@
343345

344346
$(CLA_DIR)%.md: $(CLA_DIR)%.txt | $(CLA_DIR)%.svg $(CLA_DIR)%.png
345-
echo "![A UML diagram for the $$(sed 's-class \(.*\){-\1-g' $< | sed 's/<|--/⇽/' | sed 's/<|../◁┈/' | sed -n '1p' ) class ([text version](./$(basename $@).txt), [image version](./$(basename $@).png), [svg version](./$(basename $@).svg))]($(notdir $(basename $@)).png)" > $@
347+
# In the following substitution, 's/~T~/<T>/' is for generic type parameter.
348+
echo "![A UML diagram for the \`$$(sed 's-class \(.*\){-\1-g' $< | sed 's/~T~/<T>/' | sed 's/<|--/⇽/' | sed 's/<|../◁┈/' | sed -n '1p' )\` class ([text version](./$(basename $@).txt), [image version](./$(basename $@).png), [svg version](./$(basename $@).svg))]($(notdir $(basename $@)).png)" > $@
346349

347350
$(CLA_DIR)%.svg: $(CLA_DIR)%.txt
348351
@echo "Creating $@"

source/code/projects/CList_ICollection/CList_ICollection/CList.cs

Lines changed: 57 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,50 @@ private class Cell
3939
}
4040

4141
/* Done with Cell.*/
42-
43-
// Empty
44-
public bool IsEmpty()
42+
43+
public int Count
4544
{
46-
return first == null;
45+
get
46+
{
47+
int size = 0;
48+
Cell cCell = first;
49+
while (cCell != null)
50+
{
51+
cCell = cCell.Next;
52+
size++;
53+
}
54+
return size;
55+
}
4756
}
4857

49-
// Add is simply "AddF", slightly revisited.
58+
public bool isReadOnly = false;
59+
// This attribute is not required by the interface,
60+
// but convenient to have.
61+
public bool IsReadOnly
62+
{
63+
get { return isReadOnly; }
64+
set { isReadOnly = value; }
65+
// Note that set is not required by the interface
66+
}
67+
68+
// Add is simply "AddF", slightly revisited
69+
// to account for IsReadOnly attribute.
5070
public void Add(T value)
5171
{
52-
if (isReadonly)
72+
if (isReadOnly)
5373
{
5474
throw new InvalidOperationException(
5575
"List is read-only."
5676
);
5777
}
5878
first = new Cell(value, first);
5979
}
60-
80+
6181
public void Clear()
6282
{
6383
first = null;
6484
}
65-
85+
6686
public bool Contains(T value)
6787
{
6888
bool found = false;
@@ -77,8 +97,8 @@ public bool Contains(T value)
7797
}
7898
return found;
7999
}
80-
81-
// Copies the elements of the ICollection to an Array, starting at a particular Array index.
100+
101+
// Copies the elements of the ICollection to an Array, starting at a particular Array index.
82102
public void CopyTo(T[] array, int arrayIndex)
83103
{
84104
if (array == null)
@@ -103,13 +123,38 @@ public void CopyTo(T[] array, int arrayIndex)
103123
cCell = cCell.Next;
104124
}
105125
}
126+
127+
public IEnumerator<T> GetEnumerator()
128+
{
129+
Cell cCell = first;
130+
while (cCell != null)
131+
{
132+
yield return cCell.Data;
133+
cCell = cCell.Next;
134+
}
135+
}
136+
137+
IEnumerator IEnumerable.GetEnumerator()
138+
{
139+
return this.GetEnumerator(); // call the generic version of the method
140+
}
141+
142+
/* We are done realizing the ICollection class. */
143+
144+
// Some additional methods.
145+
146+
// Empty
147+
public bool IsEmpty()
148+
{
149+
return first == null;
150+
}
106151

107152
// Remove the first node containing the value
108153
// if it exists and returns true,
109154
// returns false otherwise.
110155
public bool Remove(T value)
111156
{
112-
if (isReadonly)
157+
if (isReadOnly)
113158
{
114159
throw new InvalidOperationException(
115160
"List is read-only"
@@ -143,50 +188,11 @@ public bool Remove(T value)
143188
return removed;
144189
}
145190

146-
public int Count
147-
{
148-
get
149-
{
150-
int size = 0;
151-
Cell cCell = first;
152-
while (cCell != null)
153-
{
154-
cCell = cCell.Next;
155-
size++;
156-
}
157-
return size;
158-
}
159-
}
160-
161-
public bool isReadonly = false;
162-
public bool IsReadOnly
163-
{
164-
get { return isReadonly; }
165-
set { isReadonly = value; }
166-
}
167-
168-
public IEnumerator<T> GetEnumerator()
169-
{
170-
Cell cCell = first;
171-
while (cCell != null)
172-
{
173-
yield return cCell.Data;
174-
cCell = cCell.Next;
175-
}
176-
}
177-
178-
IEnumerator IEnumerable.GetEnumerator()
179-
{
180-
return this.GetEnumerator(); // call the generic version of the method
181-
}
182-
183-
/* We are done realizing the ICollection class. */
184-
185191
// One last method, to remove the last cell and
186192
// returns its value.
187193
public T RemoveL()
188194
{
189-
if (isReadonly)
195+
if (isReadOnly)
190196
{
191197
throw new InvalidOperationException(
192198
"List is read-only"

source/code/projects/CList_ICollection/CList_ICollection/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ static void Main(string[] args)
2626
{
2727
Console.Write(item + " ");
2828
}
29+
// Done with first example.
2930
Console.WriteLine("");
3031

3132
Console.Write(

source/diag/cla/ICollection.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,3 @@ class ICollection~T~{
99
+ GetEnumerator() IEnumerator
1010
+ Remove(item: T) bool
1111
}
12-
13-

source/lectures/data/CList_as_ICollection.md

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,32 @@ tags:
55

66
# List as ICollection
77

8-
Another way of implementing lists is to make our class realize the [ICollection interface](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.icollection-1?view=net-9.0):
8+
## Motivation
99

10+
Another way of implementing lists is to make our class realize the [ICollection interface](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.icollection-1?view=net-9.0).
1011

11-
!include diag/cla/ICollection.md
12+
Quoting [C# 12 in a Nutshell](https://www.albahari.com/nutshell/):
13+
14+
> `ICollection<T>` is the standard interface for countable collections of objects. It provides the ability to determine the size of a collection (`Count`), determine whether an item exists in the collection (`Contains`), copy the collection into an array (`ToArray`), and determine whether the collection is read-only (`IsReadOnly`).
15+
16+
Its UML diagram is as follows:
1217

13-
This requires implementing a series of properties and methods:
18+
!include diag/cla/ICollection.md
1419

20+
Providing a way of constructing a `IEnumerator<T>` object let C# iterate over our custom lists using `foreach`, so that we can for example write
1521

1622
```{download="./code/projects/CList_ICollection.zip"}
17-
!include`snippetStart="/* Done with Cell.*/", snippetEnd="/* We are done realizing the ICollection class. */"` code/projects/CList_ICollection/CList_ICollection/CList.cs
23+
!include`snippetStart="// is that we can iterate over elements of lists now:", snippetEnd="// Done with first example."` code/projects/CList_ICollection/CList_ICollection/Program.cs
1824
```
1925

26+
for `myList1` a `CList<int>` object.
27+
28+
Implementing interfaces is an excellent way of signaling to C# that our class respects certain convention on one hand, and to help programmer follow usual guidelines on the other.
2029

30+
## Implementation
31+
32+
In addition to signaling that our class realizes the interface, using `public class CList<T> : ICollection<T>`, we need to implement the following properties and methods:
33+
34+
```{download="./code/projects/CList_ICollection.zip"}
35+
!include`snippetStart="/* Done with Cell.*/", snippetEnd="/* We are done realizing the ICollection class. */"` code/projects/CList_ICollection/CList_ICollection/CList.cs
36+
```

0 commit comments

Comments
 (0)