Skip to content

Commit 3437fdf

Browse files
committed
added ObjectBackedTypedSet<T> for typed object-backed sets
1 parent 171e8ce commit 3437fdf

2 files changed

Lines changed: 173 additions & 0 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace WinUI.TableView.Collections;
6+
7+
/// <summary>
8+
/// Represents a set of objects that enforces a specific element type at runtime, providing set operations over objects
9+
/// backed by a strongly typed collection.
10+
/// </summary>
11+
internal partial class ObjectBackedTypedSet<T> : ICollection<object?>
12+
{
13+
private readonly HashSet<T?> _inner;
14+
15+
/// <summary>
16+
/// Initializes a new instance of the <see cref="ObjectBackedTypedSet{T}"/> class.
17+
/// </summary>
18+
/// <param name="inner">The inner collection of objects.</param>
19+
public ObjectBackedTypedSet(IEnumerable<object?> inner)
20+
{
21+
_inner = [.. inner.Cast<T?>()];
22+
}
23+
24+
/// <inheritdoc />
25+
public int Count => _inner.Count;
26+
27+
/// <inheritdoc />
28+
public bool IsReadOnly => false;
29+
30+
/// <inheritdoc />
31+
public void Add(object? item)
32+
{
33+
_inner.Add((T?)item);
34+
}
35+
36+
/// <inheritdoc />
37+
public void Clear()
38+
{
39+
_inner.Clear();
40+
}
41+
42+
/// <inheritdoc />
43+
public bool Contains(object? item)
44+
{
45+
return _inner.Contains((T?)item);
46+
}
47+
48+
/// <inheritdoc />
49+
public void CopyTo(object?[] array, int arrayIndex)
50+
{
51+
foreach (var item in _inner)
52+
array[arrayIndex++] = item!;
53+
}
54+
55+
/// <inheritdoc />
56+
public IEnumerator<object?> GetEnumerator()
57+
{
58+
foreach (var item in _inner)
59+
yield return item;
60+
}
61+
62+
/// <inheritdoc />
63+
public bool Remove(object? item)
64+
{
65+
return _inner.Remove((T?)item);
66+
}
67+
68+
/// <inheritdoc />
69+
IEnumerator IEnumerable.GetEnumerator()
70+
{
71+
return GetEnumerator();
72+
}
73+
}

tests/ObjectBackedTypedSetTests.cs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
using Microsoft.VisualStudio.TestTools.UnitTesting;
2+
using System;
3+
using System.Collections.Generic;
4+
using WinUI.TableView.Collections;
5+
6+
namespace WinUI.TableView.Tests;
7+
8+
[TestClass]
9+
public class ObjectBackedTypedSetTests
10+
{
11+
[TestMethod]
12+
public void Construct_FromObjects_CastsToType()
13+
{
14+
var source = new object?[] { 1, 2, 3, null };
15+
var set = new ObjectBackedTypedSet<int?>(source);
16+
Assert.AreEqual(4, set.Count);
17+
Assert.IsTrue(set.Contains(1));
18+
Assert.IsTrue(set.Contains(2));
19+
Assert.IsTrue(set.Contains(3));
20+
Assert.IsTrue(set.Contains(null));
21+
}
22+
23+
[TestMethod]
24+
public void Add_TypedItem_IncreasesCount()
25+
{
26+
var set = new ObjectBackedTypedSet<string>(["a"]);
27+
Assert.AreEqual(1, set.Count);
28+
set.Add("b");
29+
Assert.AreEqual(2, set.Count);
30+
Assert.IsTrue(set.Contains("b"));
31+
}
32+
33+
[TestMethod]
34+
public void Add_Null_AddsDefault()
35+
{
36+
var set = new ObjectBackedTypedSet<string>([]);
37+
Assert.AreEqual(0, set.Count);
38+
set.Add(null);
39+
Assert.AreEqual(1, set.Count);
40+
Assert.IsTrue(set.Contains(null));
41+
}
42+
43+
[TestMethod]
44+
public void Remove_TypedItem_Removes()
45+
{
46+
var set = new ObjectBackedTypedSet<int>([1, 2]);
47+
Assert.AreEqual(2, set.Count);
48+
var removed = set.Remove(1);
49+
Assert.IsTrue(removed);
50+
Assert.AreEqual(1, set.Count);
51+
Assert.IsFalse(set.Contains(1));
52+
}
53+
54+
[TestMethod]
55+
public void Remove_Null_RemovesDefault()
56+
{
57+
var set = new ObjectBackedTypedSet<string>([null, "x"]);
58+
var removed = set.Remove(null);
59+
Assert.IsTrue(removed);
60+
Assert.AreEqual(1, set.Count);
61+
Assert.IsFalse(set.Contains(null));
62+
}
63+
64+
[TestMethod]
65+
public void CopyTo_CopiesAllElements_InOrderOfEnumeration()
66+
{
67+
var set = new ObjectBackedTypedSet<int>([1, 2, 3]);
68+
var arr = new object?[5];
69+
set.CopyTo(arr, 1);
70+
// HashSet iteration order is unspecified; validate membership and positions filled
71+
var nonNullCount = 0;
72+
for (var i = 1; i <= 3; i++) if (arr[i] != null) nonNullCount++;
73+
Assert.AreEqual(3, nonNullCount);
74+
CollectionAssert.Contains(arr, 1);
75+
CollectionAssert.Contains(arr, 2);
76+
CollectionAssert.Contains(arr, 3);
77+
}
78+
79+
[TestMethod]
80+
public void Enumerator_YieldsObjects()
81+
{
82+
var set = new ObjectBackedTypedSet<int>([7, 8]);
83+
var collected = new List<object?>();
84+
foreach (var o in set)
85+
{
86+
collected.Add(o);
87+
}
88+
Assert.AreEqual(2, collected.Count);
89+
CollectionAssert.Contains(collected, 7);
90+
CollectionAssert.Contains(collected, 8);
91+
}
92+
93+
[TestMethod]
94+
public void Clear_EmptiesSet()
95+
{
96+
var set = new ObjectBackedTypedSet<int>([1, 2]);
97+
set.Clear();
98+
Assert.AreEqual(0, set.Count);
99+
}
100+
}

0 commit comments

Comments
 (0)