diff --git a/src/Foundation/NSMutableSet_1.cs b/src/Foundation/NSMutableSet_1.cs
index e83c185b8f29..253d70014916 100644
--- a/src/Foundation/NSMutableSet_1.cs
+++ b/src/Foundation/NSMutableSet_1.cs
@@ -27,30 +27,26 @@
using System.Collections;
using System.Collections.Generic;
-// Disable until we get around to enable + fix any issues.
-#nullable disable
+#nullable enable
namespace Foundation {
- [SupportedOSPlatform ("ios")]
- [SupportedOSPlatform ("maccatalyst")]
- [SupportedOSPlatform ("macos")]
- [SupportedOSPlatform ("tvos")]
+ /// A strongly-typed mutable set that contains objects of type .
+ /// The type of objects in the set.
[Register ("NSMutableSet", SkipRegistration = true)]
public sealed partial class NSMutableSet : NSMutableSet, IEnumerable
where TKey : class, INativeObject {
- /// To be added.
- /// To be added.
+ /// Initializes a new empty mutable set.
public NSMutableSet ()
{
}
+ /// Initializes the object from the data stored in the unarchiver object.
/// The unarchiver object.
- /// A constructor that initializes the object from the data stored in the unarchiver object.
- ///
- /// This constructor is provided to allow the class to be initialized from an unarchiver (for example, during NIB deserialization). This is part of the protocol.
- /// If developers want to create a subclass of this object and continue to support deserialization from an archive, they should implement a constructor with an identical signature: taking a single parameter of type and decorate it with the [Export("initWithCoder:"] attribute declaration.
- /// The state of this object can also be serialized by using the companion method, EncodeTo.
- ///
+ ///
+ /// This constructor is provided to allow the class to be initialized from an unarchiver (for example, during NIB deserialization). This is part of the protocol.
+ /// If developers want to create a subclass of this object and continue to support deserialization from an archive, they should implement a constructor with an identical signature: taking a single parameter of type and decorate it with the [Export("initWithCoder:"] attribute declaration.
+ /// The state of this object can also be serialized by using the companion method, EncodeTo.
+ ///
public NSMutableSet (NSCoder coder)
: base (coder)
{
@@ -61,33 +57,29 @@ internal NSMutableSet (NativeHandle handle)
{
}
- /// To be added.
- /// To be added.
- /// To be added.
+ /// Initializes a new mutable set with the specified objects.
+ /// The objects to add to the set.
public NSMutableSet (params TKey [] objs)
: base (objs)
{
}
- /// To be added.
- /// To be added.
- /// To be added.
+ /// Initializes a new mutable set with the contents of the specified set.
+ /// The set whose contents will be copied to the new set.
public NSMutableSet (NSSet other)
: base (other)
{
}
- /// To be added.
- /// To be added.
- /// To be added.
+ /// Initializes a new mutable set with the contents of the specified mutable set.
+ /// The mutable set whose contents will be copied to the new set.
public NSMutableSet (NSMutableSet other)
: base (other)
{
}
- /// To be added.
- /// To be added.
- /// To be added.
+ /// Initializes a new mutable set with the specified initial capacity.
+ /// The initial capacity of the set.
public NSMutableSet (nint capacity)
: base (capacity)
{
@@ -95,33 +87,30 @@ public NSMutableSet (nint capacity)
// Strongly typed versions of API from NSSet
- /// To be added.
- /// To be added.
- /// To be added.
- /// To be added.
- public TKey LookupMember (TKey probe)
+ /// Returns the object in the set that is equal to the specified object.
+ /// The object to search for in the set.
+ /// The object in the set that is equal to , or if no such object exists.
+ public TKey? LookupMember (TKey probe)
{
if (probe is null)
throw new ArgumentNullException (nameof (probe));
- TKey result = Runtime.GetINativeObject (_LookupMember (probe.Handle), false);
+ TKey? result = Runtime.GetINativeObject (_LookupMember (probe.Handle), false);
GC.KeepAlive (probe);
return result;
}
- /// To be added.
- /// To be added.
- /// To be added.
- public TKey AnyObject {
+ /// Gets one of the objects in the set, or if the set is empty.
+ /// An arbitrary object from the set, or if the set contains no objects.
+ public TKey? AnyObject {
get {
return Runtime.GetINativeObject (_AnyObject, false);
}
}
- /// To be added.
- /// To be added.
- /// To be added.
- /// To be added.
+ /// Determines whether the set contains the specified object.
+ /// The object to locate in the set.
+ /// if the set contains ; otherwise, .
public bool Contains (TKey obj)
{
if (obj is null)
@@ -132,18 +121,23 @@ public bool Contains (TKey obj)
return result;
}
- /// To be added.
- /// To be added.
- /// To be added.
+ /// Converts the set to an array.
+ /// An array containing all the objects in the set.
public TKey [] ToArray ()
{
return base.ToArray ();
}
- public static NSMutableSet operator + (NSMutableSet first, NSMutableSet second)
+ /// Creates a new mutable set containing all objects from both sets.
+ /// The first set.
+ /// The second set.
+ /// A new containing the union of both sets, or if both sets are .
+ public static NSMutableSet? operator + (NSMutableSet? first, NSMutableSet? second)
{
+ if (first is null && second is null)
+ return null;
if (first is null || first.Count == 0)
- return new NSMutableSet (second);
+ return second is null ? new NSMutableSet () : new NSMutableSet (second);
if (second is null || second.Count == 0)
return new NSMutableSet (first);
var result = new NSMutableSet (first._SetByAddingObjectsFromSet (second.Handle));
@@ -151,7 +145,11 @@ public TKey [] ToArray ()
return result;
}
- public static NSMutableSet operator - (NSMutableSet first, NSMutableSet second)
+ /// Creates a new mutable set with objects from the first set that are not in the second set.
+ /// The first set.
+ /// The second set.
+ /// A new containing the difference, or if the first set is or empty.
+ public static NSMutableSet? operator - (NSMutableSet? first, NSMutableSet? second)
{
if (first is null || first.Count == 0)
return null;
@@ -163,9 +161,8 @@ public TKey [] ToArray ()
}
// Strongly typed versions of API from NSMutableSet
- /// To be added.
- /// To be added.
- /// To be added.
+ /// Adds the specified object to the set.
+ /// The object to add to the set.
public void Add (TKey obj)
{
if (obj is null)
@@ -175,9 +172,8 @@ public void Add (TKey obj)
GC.KeepAlive (obj);
}
- /// To be added.
- /// To be added.
- /// To be added.
+ /// Removes the specified object from the set.
+ /// The object to remove from the set.
public void Remove (TKey obj)
{
if (obj is null)
@@ -187,9 +183,8 @@ public void Remove (TKey obj)
GC.KeepAlive (obj);
}
- /// To be added.
- /// To be added.
- /// To be added.
+ /// Adds multiple objects to the set.
+ /// The objects to add to the set.
public void AddObjects (params TKey [] objects)
{
if (objects is null)
@@ -213,9 +208,8 @@ public void AddObjects (params TKey [] objects)
#endregion
#region IEnumerable implementation
- /// To be added.
- /// To be added.
- /// To be added.
+ /// Returns an enumerator that iterates through the set.
+ /// An enumerator that can be used to iterate through the set.
IEnumerator IEnumerable.GetEnumerator ()
{
return new NSFastEnumerator (this);
diff --git a/tests/cecil-tests/Documentation.KnownFailures.txt b/tests/cecil-tests/Documentation.KnownFailures.txt
index 71f012496e33..b6509eca7635 100644
--- a/tests/cecil-tests/Documentation.KnownFailures.txt
+++ b/tests/cecil-tests/Documentation.KnownFailures.txt
@@ -11861,8 +11861,6 @@ M:Foundation.NSMutableOrderedSet`1.op_Subtraction(Foundation.NSMutableOrderedSet
M:Foundation.NSMutableOrderedSet`1.op_Subtraction(Foundation.NSMutableOrderedSet{`0},Foundation.NSSet{`0})
M:Foundation.NSMutableSet.op_Addition(Foundation.NSMutableSet,Foundation.NSMutableSet)
M:Foundation.NSMutableSet.op_Subtraction(Foundation.NSMutableSet,Foundation.NSMutableSet)
-M:Foundation.NSMutableSet`1.op_Addition(Foundation.NSMutableSet{`0},Foundation.NSMutableSet{`0})
-M:Foundation.NSMutableSet`1.op_Subtraction(Foundation.NSMutableSet{`0},Foundation.NSMutableSet{`0})
M:Foundation.NSNetService.add_AddressResolved(System.EventHandler)
M:Foundation.NSNetService.add_DidAcceptConnection(System.EventHandler{Foundation.NSNetServiceConnectionEventArgs})
M:Foundation.NSNetService.add_Published(System.EventHandler)
diff --git a/tests/monotouch-test/Foundation/NSMutableSet1Test.cs b/tests/monotouch-test/Foundation/NSMutableSet1Test.cs
index 68ee6f9c6145..c3014749dd10 100644
--- a/tests/monotouch-test/Foundation/NSMutableSet1Test.cs
+++ b/tests/monotouch-test/Foundation/NSMutableSet1Test.cs
@@ -266,5 +266,335 @@ public void OperatorPlusReferenceTest ()
Assert.AreNotEqual (IntPtr.Zero, one.Handle, "Handle must be != IntPtr.Zero");
Assert.AreNotEqual (IntPtr.Zero, two.Handle, "Handle must be != IntPtr.Zero");
}
+
+ [Test]
+ public void OperatorPlus_BothNull ()
+ {
+ NSMutableSet first = null;
+ NSMutableSet second = null;
+ var result = first + second;
+ Assert.IsNull (result, "Both null should return null");
+ }
+
+ [Test]
+ public void OperatorPlus_FirstNull ()
+ {
+ NSMutableSet first = null;
+ using (var second = new NSMutableSet ((NSString) "1", (NSString) "2")) {
+ using (var result = first + second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 2, result.Count, "Count");
+ Assert.IsTrue (result.Contains ((NSString) "1"), "Contains 1");
+ Assert.IsTrue (result.Contains ((NSString) "2"), "Contains 2");
+ }
+ }
+ }
+
+ [Test]
+ public void OperatorPlus_SecondNull ()
+ {
+ using (var first = new NSMutableSet ((NSString) "1", (NSString) "2")) {
+ NSMutableSet second = null;
+ using (var result = first + second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 2, result.Count, "Count");
+ Assert.IsTrue (result.Contains ((NSString) "1"), "Contains 1");
+ Assert.IsTrue (result.Contains ((NSString) "2"), "Contains 2");
+ }
+ }
+ }
+
+ [Test]
+ public void OperatorPlus_BothEmpty ()
+ {
+ using (var first = new NSMutableSet ())
+ using (var second = new NSMutableSet ())
+ using (var result = first + second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 0, result.Count, "Count should be 0");
+ }
+ }
+
+ [Test]
+ public void OperatorPlus_FirstEmpty ()
+ {
+ using (var first = new NSMutableSet ())
+ using (var second = new NSMutableSet ((NSString) "1", (NSString) "2"))
+ using (var result = first + second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 2, result.Count, "Count");
+ Assert.IsTrue (result.Contains ((NSString) "1"), "Contains 1");
+ Assert.IsTrue (result.Contains ((NSString) "2"), "Contains 2");
+ }
+ }
+
+ [Test]
+ public void OperatorPlus_SecondEmpty ()
+ {
+ using (var first = new NSMutableSet ((NSString) "1", (NSString) "2"))
+ using (var second = new NSMutableSet ())
+ using (var result = first + second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 2, result.Count, "Count");
+ Assert.IsTrue (result.Contains ((NSString) "1"), "Contains 1");
+ Assert.IsTrue (result.Contains ((NSString) "2"), "Contains 2");
+ }
+ }
+
+ [Test]
+ public void OperatorPlus_Overlapping ()
+ {
+ using (var first = new NSMutableSet ((NSString) "1", (NSString) "2"))
+ using (var second = new NSMutableSet ((NSString) "2", (NSString) "3"))
+ using (var result = first + second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 3, result.Count, "Count should be 3 (set union)");
+ Assert.IsTrue (result.Contains ((NSString) "1"), "Contains 1");
+ Assert.IsTrue (result.Contains ((NSString) "2"), "Contains 2");
+ Assert.IsTrue (result.Contains ((NSString) "3"), "Contains 3");
+ }
+ }
+
+ [Test]
+ public void OperatorMinus_BothNull ()
+ {
+ NSMutableSet first = null;
+ NSMutableSet second = null;
+ var result = first - second;
+ Assert.IsNull (result, "Both null should return null");
+ }
+
+ [Test]
+ public void OperatorMinus_FirstNull ()
+ {
+ NSMutableSet first = null;
+ using (var second = new NSMutableSet ((NSString) "1", (NSString) "2")) {
+ var result = first - second;
+ Assert.IsNull (result, "First null should return null");
+ }
+ }
+
+ [Test]
+ public void OperatorMinus_SecondNull ()
+ {
+ using (var first = new NSMutableSet ((NSString) "1", (NSString) "2")) {
+ NSMutableSet second = null;
+ using (var result = first - second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 2, result.Count, "Count");
+ Assert.IsTrue (result.Contains ((NSString) "1"), "Contains 1");
+ Assert.IsTrue (result.Contains ((NSString) "2"), "Contains 2");
+ }
+ }
+ }
+
+ [Test]
+ public void OperatorMinus_FirstEmpty ()
+ {
+ using (var first = new NSMutableSet ())
+ using (var second = new NSMutableSet ((NSString) "1", (NSString) "2")) {
+ var result = first - second;
+ Assert.IsNull (result, "Empty first should return null");
+ }
+ }
+
+ [Test]
+ public void OperatorMinus_SecondEmpty ()
+ {
+ using (var first = new NSMutableSet ((NSString) "1", (NSString) "2"))
+ using (var second = new NSMutableSet ())
+ using (var result = first - second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 2, result.Count, "Count");
+ Assert.IsTrue (result.Contains ((NSString) "1"), "Contains 1");
+ Assert.IsTrue (result.Contains ((NSString) "2"), "Contains 2");
+ }
+ }
+
+ [Test]
+ public void OperatorMinus_BothEmpty ()
+ {
+ using (var first = new NSMutableSet ())
+ using (var second = new NSMutableSet ()) {
+ var result = first - second;
+ Assert.IsNull (result, "Both empty should return null");
+ }
+ }
+
+ [Test]
+ public void OperatorMinus_NoOverlap ()
+ {
+ using (var first = new NSMutableSet ((NSString) "1", (NSString) "2"))
+ using (var second = new NSMutableSet ((NSString) "3", (NSString) "4"))
+ using (var result = first - second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 2, result.Count, "Count");
+ Assert.IsTrue (result.Contains ((NSString) "1"), "Contains 1");
+ Assert.IsTrue (result.Contains ((NSString) "2"), "Contains 2");
+ }
+ }
+
+ [Test]
+ public void OperatorMinus_PartialOverlap ()
+ {
+ using (var first = new NSMutableSet ((NSString) "1", (NSString) "2", (NSString) "3"))
+ using (var second = new NSMutableSet ((NSString) "2", (NSString) "4"))
+ using (var result = first - second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 2, result.Count, "Count");
+ Assert.IsTrue (result.Contains ((NSString) "1"), "Contains 1");
+ Assert.IsTrue (result.Contains ((NSString) "3"), "Contains 3");
+ Assert.IsFalse (result.Contains ((NSString) "2"), "Should not contain 2");
+ }
+ }
+
+ [Test]
+ public void OperatorMinus_CompleteOverlap ()
+ {
+ using (var first = new NSMutableSet ((NSString) "1", (NSString) "2"))
+ using (var second = new NSMutableSet ((NSString) "1", (NSString) "2"))
+ using (var result = first - second) {
+ Assert.IsNotNull (result, "Result should not be null");
+ Assert.AreEqual ((nuint) 0, result.Count, "Count should be 0");
+ }
+ }
+
+ [Test]
+ public void Ctor_Capacity ()
+ {
+ using (var set = new NSMutableSet (10)) {
+ Assert.AreEqual ((nuint) 0, set.Count, "Empty with capacity");
+ }
+ }
+
+ [Test]
+ public void ToArray_Empty ()
+ {
+ using (var set = new NSMutableSet ()) {
+ var arr = set.ToArray ();
+ Assert.IsNotNull (arr, "Array should not be null");
+ Assert.AreEqual (0, arr.Length, "Length should be 0");
+ }
+ }
+
+ [Test]
+ public void ToArray_Multiple ()
+ {
+ var v1 = (NSString) "1";
+ var v2 = (NSString) "2";
+ var v3 = (NSString) "3";
+
+ using (var set = new NSMutableSet (v1, v2, v3)) {
+ var arr = set.ToArray ();
+ Assert.AreEqual (3, arr.Length, "Length");
+ Assert.Contains (v1, arr, "Contains v1");
+ Assert.Contains (v2, arr, "Contains v2");
+ Assert.Contains (v3, arr, "Contains v3");
+ }
+ }
+
+ [Test]
+ public void Add_Duplicate ()
+ {
+ var v1 = (NSString) "1";
+
+ using (var set = new NSMutableSet ()) {
+ set.Add (v1);
+ Assert.AreEqual ((nuint) 1, set.Count, "Count after first add");
+
+ set.Add (v1);
+ Assert.AreEqual ((nuint) 1, set.Count, "Count after duplicate add");
+ }
+ }
+
+ [Test]
+ public void Remove_NonExistent ()
+ {
+ var v1 = (NSString) "1";
+ var v2 = (NSString) "2";
+
+ using (var set = new NSMutableSet (v1)) {
+ set.Remove (v2);
+ Assert.AreEqual ((nuint) 1, set.Count, "Count should remain 1");
+ Assert.IsTrue (set.Contains (v1), "Should still contain v1");
+ }
+ }
+
+ [Test]
+ public void AddObjects_Empty ()
+ {
+ using (var set = new NSMutableSet ()) {
+ set.AddObjects ();
+ Assert.AreEqual ((nuint) 0, set.Count, "Count should be 0");
+ }
+ }
+
+ [Test]
+ public void AddObjects_WithNullElement ()
+ {
+ var v1 = (NSString) "1";
+
+ using (var set = new NSMutableSet ()) {
+ Assert.Throws (() => set.AddObjects (v1, null), "Should throw on null element");
+ }
+ }
+
+ [Test]
+ public void LookupMember_Empty ()
+ {
+ var v1 = (NSString) "1";
+
+ using (var set = new NSMutableSet ()) {
+ var result = set.LookupMember (v1);
+ Assert.IsNull (result, "Should return null for empty set");
+ }
+ }
+
+ [Test]
+ public void Contains_Empty ()
+ {
+ var v1 = (NSString) "1";
+
+ using (var set = new NSMutableSet ()) {
+ Assert.IsFalse (set.Contains (v1), "Empty set should not contain any element");
+ }
+ }
+
+ [Test]
+ public void Enumeration_Empty ()
+ {
+ using (var set = new NSMutableSet ()) {
+ var count = 0;
+ foreach (var item in set) {
+ count++;
+ }
+ Assert.AreEqual (0, count, "Should not enumerate any items");
+ }
+ }
+
+ [Test]
+ public void Enumeration_Single ()
+ {
+ var v1 = (NSString) "1";
+
+ using (var set = new NSMutableSet (v1)) {
+ var count = 0;
+ NSString found = null;
+ foreach (var item in set) {
+ count++;
+ found = item;
+ }
+ Assert.AreEqual (1, count, "Should enumerate one item");
+ Assert.AreSame (v1, found, "Should find v1");
+ }
+ }
+
+ [Test]
+ public void Ctor_Params_Empty ()
+ {
+ using (var set = new NSMutableSet ()) {
+ Assert.AreEqual ((nuint) 0, set.Count, "Empty params");
+ }
+ }
}
}