diff --git a/src/Foundation/NSDictionary.cs b/src/Foundation/NSDictionary.cs index 1cb081fbd3fd..c4f4c3d1ec46 100644 --- a/src/Foundation/NSDictionary.cs +++ b/src/Foundation/NSDictionary.cs @@ -129,6 +129,40 @@ internal static NSArray PickOdd (object f, object [] args) return NSArray.FromObjects (ret); } + // Checks: + // * 'objects' and 'keys' for null + // * count isn't negative + // * count isn't higher than the number of elements in either array + // returns false if an empty dictionary can be returned + private protected static bool ValidateFromObjectsAndKeys (T [] objects, K [] keys, nint count) + { + ArgumentNullException.ThrowIfNull (objects); + ArgumentNullException.ThrowIfNull (keys); + + if (count < 0) + throw new ArgumentOutOfRangeException (nameof (count), "Must be non-negative and not greater than the length of either array"); + + if (objects.Length < count || keys.Length < count) + throw new ArgumentException ("Must be non-negative and not greater than the length of either array", nameof (count)); + + return count > 0; + } + + // Checks: + // * 'objects' and 'keys' for null + // * 'objects' and 'keys' have the same number of elements + // returns false if an empty dictionary can be returned + private protected static bool ValidateFromObjectsAndKeys (T [] objects, K [] keys) + { + ArgumentNullException.ThrowIfNull (objects); + ArgumentNullException.ThrowIfNull (keys); + + if (objects.Length != keys.Length) + throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); + + return objects.Length > 0; + } + /// /// Creates a dictionary from a set of values and keys. /// @@ -137,14 +171,10 @@ internal static NSArray PickOdd (object f, object [] args) /// A new containing the specified key-value pairs. public static NSDictionary FromObjectsAndKeys (NSObject? [] objects, NSObject [] keys) { - if (objects is null) - throw new ArgumentNullException (nameof (objects)); - if (keys is null) - throw new ArgumentNullException (nameof (keys)); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); + if (!ValidateFromObjectsAndKeys (objects, keys)) + return new NSDictionary (); - return FromObjectsAndKeys (objects, keys, keys.Length); + return FromObjectsAndKeys (objects, keys, objects.Length); } /// @@ -160,16 +190,10 @@ public static NSDictionary FromObjectsAndKeys (NSObject? [] objects, NSObject [] /// public static NSDictionary FromObjectsAndKeys (object [] objects, object [] keys) { - if (objects is null) - throw new ArgumentNullException (nameof (objects)); - if (keys is null) - throw new ArgumentNullException (nameof (keys)); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); + if (!ValidateFromObjectsAndKeys (objects, keys)) + return new NSDictionary (); - using (var no = NSArray.FromObjects (objects)) - using (var nk = NSArray.FromObjects (keys)) - return FromObjectsAndKeysInternal (no, nk); + return FromObjectsAndKeys (objects, keys, objects.Length); } /// @@ -177,18 +201,12 @@ public static NSDictionary FromObjectsAndKeys (object [] objects, object [] keys /// /// Array of values for the dictionary. Null elements are stored as . /// Array of keys for the dictionary. - /// Number of items to use in the creation; the number must be less than or equal to the number of elements in the arrays. + /// Number of items to use in the creation; the number must be less than or equal to the number of elements in both arrays. /// A new containing the specified key-value pairs. public static NSDictionary FromObjectsAndKeys (NSObject? [] objects, NSObject [] keys, nint count) { - if (objects is null) - throw new ArgumentNullException (nameof (objects)); - if (keys is null) - throw new ArgumentNullException (nameof (keys)); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - if (count < 1 || objects.Length < count || keys.Length < count) - throw new ArgumentException ("count"); + if (!ValidateFromObjectsAndKeys (objects, keys, count)) + return new NSDictionary (); using (var no = NSArray.FromNativeObjects (objects, count)) using (var nk = NSArray.FromNativeObjects (keys, count)) @@ -200,7 +218,7 @@ public static NSDictionary FromObjectsAndKeys (NSObject? [] objects, NSObject [] /// /// Array of values for the dictionary. /// Array of keys for the dictionary. - /// Number of items to use in the creation; the number must be less than or equal to the number of elements in the arrays. + /// Number of items to use in the creation; the number must be less than or equal to the number of elements in both arrays. /// A new containing the specified key-value pairs. /// /// @@ -209,14 +227,8 @@ public static NSDictionary FromObjectsAndKeys (NSObject? [] objects, NSObject [] /// public static NSDictionary FromObjectsAndKeys (object [] objects, object [] keys, nint count) { - if (objects is null) - throw new ArgumentNullException (nameof (objects)); - if (keys is null) - throw new ArgumentNullException (nameof (keys)); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - if (count < 1 || objects.Length < count || keys.Length < count) - throw new ArgumentException ("count"); + if (!ValidateFromObjectsAndKeys (objects, keys, count)) + return new NSDictionary (); using (var no = NSArray.FromObjects (count, objects)) using (var nk = NSArray.FromObjects (count, keys)) diff --git a/src/Foundation/NSDictionary_2.cs b/src/Foundation/NSDictionary_2.cs index 661d7760a002..23468bfae958 100644 --- a/src/Foundation/NSDictionary_2.cs +++ b/src/Foundation/NSDictionary_2.cs @@ -256,13 +256,8 @@ static NSDictionary GenericFromObjectsAndKeysInternal (NSArray obj /// A new dictionary containing the specified key-value pairs. public static NSDictionary FromObjectsAndKeys (TValue? [] objects, TKey [] keys, nint count) { - ArgumentNullException.ThrowIfNull (objects); - ArgumentNullException.ThrowIfNull (keys); - - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - if (count < 1 || objects.Length < count) - throw new ArgumentException (nameof (count)); + if (!ValidateFromObjectsAndKeys (objects, keys, count)) + return new NSDictionary (); using (var no = NSArray.FromNativeObjects (objects, count)) using (var nk = NSArray.FromNativeObjects (keys, count)) @@ -277,13 +272,10 @@ public static NSDictionary FromObjectsAndKeys (TValue? [] objects, /// A new dictionary containing the specified key-value pairs. public static NSDictionary FromObjectsAndKeys (TValue? [] objects, TKey [] keys) { - ArgumentNullException.ThrowIfNull (objects); - ArgumentNullException.ThrowIfNull (keys); + if (!ValidateFromObjectsAndKeys (objects, keys)) + return new NSDictionary (); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - - return FromObjectsAndKeys (objects, keys, keys.Length); + return FromObjectsAndKeys (objects, keys, objects.Length); } /// @@ -294,15 +286,10 @@ public static NSDictionary FromObjectsAndKeys (TValue? [] objects, /// A new dictionary containing the specified key-value pairs. public static NSDictionary FromObjectsAndKeys (object [] objects, object [] keys) { - ArgumentNullException.ThrowIfNull (objects); - ArgumentNullException.ThrowIfNull (keys); - - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); + if (!ValidateFromObjectsAndKeys (objects, keys)) + return new NSDictionary (); - using (var no = NSArray.FromObjects (objects)) - using (var nk = NSArray.FromObjects (keys)) - return GenericFromObjectsAndKeysInternal (no, nk); + return FromObjectsAndKeys (objects, keys, objects.Length); } /// @@ -314,13 +301,8 @@ public static NSDictionary FromObjectsAndKeys (object [] objects, /// A new dictionary containing the specified key-value pairs. public static NSDictionary FromObjectsAndKeys (NSObject? [] objects, NSObject [] keys, nint count) { - ArgumentNullException.ThrowIfNull (objects); - ArgumentNullException.ThrowIfNull (keys); - - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - if (count < 1 || objects.Length < count || keys.Length < count) - throw new ArgumentException (nameof (count)); + if (!ValidateFromObjectsAndKeys (objects, keys, count)) + return new NSDictionary (); using (var no = NSArray.FromNativeObjects (objects, count)) using (var nk = NSArray.FromNativeObjects (keys, count)) @@ -336,13 +318,8 @@ public static NSDictionary FromObjectsAndKeys (NSObject? [] object /// A new dictionary containing the specified key-value pairs. public static NSDictionary FromObjectsAndKeys (object [] objects, object [] keys, nint count) { - ArgumentNullException.ThrowIfNull (objects); - ArgumentNullException.ThrowIfNull (keys); - - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - if (count < 1 || objects.Length < count || keys.Length < count) - throw new ArgumentException (nameof (count)); + if (!ValidateFromObjectsAndKeys (objects, keys, count)) + return new NSDictionary (); using (var no = NSArray.FromObjects (count, objects)) using (var nk = NSArray.FromObjects (count, keys)) diff --git a/src/Foundation/NSMutableDictionary.cs b/src/Foundation/NSMutableDictionary.cs index 10a572a9896a..a6587a32f2ea 100644 --- a/src/Foundation/NSMutableDictionary.cs +++ b/src/Foundation/NSMutableDictionary.cs @@ -41,16 +41,10 @@ public partial class NSMutableDictionary : NSDictionary, IDictionary, IDictionar /// Thrown when the arrays have different sizes. public static NSMutableDictionary FromObjectsAndKeys (NSObject [] objects, NSObject [] keys) { - if (objects is null) - throw new ArgumentNullException (nameof (objects)); - if (keys is null) - throw new ArgumentNullException (nameof (keys)); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - - using (var no = NSArray.FromNSObjects (objects)) - using (var nk = NSArray.FromNSObjects (keys)) - return FromObjectsAndKeysInternal (no, nk); + if (!ValidateFromObjectsAndKeys (objects, keys)) + return new NSMutableDictionary (); + + return FromObjectsAndKeys (objects, keys, objects.Length); } /// Creates a mutable dictionary from the specified arrays of objects and keys. @@ -61,16 +55,10 @@ public static NSMutableDictionary FromObjectsAndKeys (NSObject [] objects, NSObj /// Thrown when the arrays have different sizes. public static NSMutableDictionary FromObjectsAndKeys (object [] objects, object [] keys) { - if (objects is null) - throw new ArgumentNullException (nameof (objects)); - if (keys is null) - throw new ArgumentNullException (nameof (keys)); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - - using (var no = NSArray.FromObjects (objects)) - using (var nk = NSArray.FromObjects (keys)) - return FromObjectsAndKeysInternal (no, nk); + if (!ValidateFromObjectsAndKeys (objects, keys)) + return new NSMutableDictionary (); + + return FromObjectsAndKeys (objects, keys, objects.Length); } /// Creates a mutable dictionary from the specified number of objects and keys from the arrays. @@ -79,20 +67,14 @@ public static NSMutableDictionary FromObjectsAndKeys (object [] objects, object /// The number of elements to copy from the arrays. /// A new mutable dictionary containing the specified objects and keys. /// Thrown when or is . - /// Thrown when the arrays have different sizes or is invalid. + /// Thrown when is invalid. public static NSMutableDictionary FromObjectsAndKeys (NSObject [] objects, NSObject [] keys, nint count) { - if (objects is null) - throw new ArgumentNullException (nameof (objects)); - if (keys is null) - throw new ArgumentNullException (nameof (keys)); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - if (count < 1 || objects.Length < count || keys.Length < count) - throw new ArgumentException (nameof (count)); - - using (var no = NSArray.FromNSObjects (objects)) - using (var nk = NSArray.FromNSObjects (keys)) + if (!ValidateFromObjectsAndKeys (objects, keys, count)) + return new NSMutableDictionary (); + + using (var no = NSArray.FromNativeObjects (objects, count)) + using (var nk = NSArray.FromNativeObjects (keys, count)) return FromObjectsAndKeysInternal (no, nk); } @@ -102,20 +84,14 @@ public static NSMutableDictionary FromObjectsAndKeys (NSObject [] objects, NSObj /// The number of elements to copy from the arrays. /// A new mutable dictionary containing the specified objects and keys. /// Thrown when or is . - /// Thrown when the arrays have different sizes or is invalid. + /// Thrown when is invalid. public static NSMutableDictionary FromObjectsAndKeys (object [] objects, object [] keys, nint count) { - if (objects is null) - throw new ArgumentNullException (nameof (objects)); - if (keys is null) - throw new ArgumentNullException (nameof (keys)); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - if (count < 1 || objects.Length < count || keys.Length < count) - throw new ArgumentException (nameof (count)); - - using (var no = NSArray.FromObjects (objects)) - using (var nk = NSArray.FromObjects (keys)) + if (!ValidateFromObjectsAndKeys (objects, keys, count)) + return new NSMutableDictionary (); + + using (var no = NSArray.FromObjects (count, objects)) + using (var nk = NSArray.FromObjects (count, keys)) return FromObjectsAndKeysInternal (no, nk); } diff --git a/src/Foundation/NSMutableDictionary_2.cs b/src/Foundation/NSMutableDictionary_2.cs index 590951e18f1c..473efef936af 100644 --- a/src/Foundation/NSMutableDictionary_2.cs +++ b/src/Foundation/NSMutableDictionary_2.cs @@ -265,15 +265,11 @@ public TValue? this [TKey index] { /// A new mutable dictionary containing the specified key-value pairs. public static NSMutableDictionary? FromObjectsAndKeys (TValue [] objects, TKey [] keys, nint count) { - ArgumentNullException.ThrowIfNull (objects); - ArgumentNullException.ThrowIfNull (keys); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - if (count < 1 || objects.Length < count) - throw new ArgumentException (nameof (count)); + if (!ValidateFromObjectsAndKeys (objects, keys, count)) + return new NSMutableDictionary (); - using (var no = NSArray.FromNSObjects (objects)) - using (var nk = NSArray.FromNSObjects (keys)) + using (var no = NSArray.FromNativeObjects (objects, count)) + using (var nk = NSArray.FromNativeObjects (keys, count)) return GenericFromObjectsAndKeysInternal (no, nk); } @@ -285,14 +281,10 @@ public TValue? this [TKey index] { /// A new mutable dictionary containing the specified key-value pairs. public static NSMutableDictionary? FromObjectsAndKeys (TValue [] objects, TKey [] keys) { - ArgumentNullException.ThrowIfNull (objects); - ArgumentNullException.ThrowIfNull (keys); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); + if (!ValidateFromObjectsAndKeys (objects, keys)) + return new NSMutableDictionary (); - using (var no = NSArray.FromNSObjects (objects)) - using (var nk = NSArray.FromNSObjects (keys)) - return GenericFromObjectsAndKeysInternal (no, nk); + return FromObjectsAndKeys (objects, keys, objects.Length); } /// @@ -303,14 +295,10 @@ public TValue? this [TKey index] { /// A new mutable dictionary containing the specified key-value pairs. public static NSMutableDictionary? FromObjectsAndKeys (object [] objects, object [] keys) { - ArgumentNullException.ThrowIfNull (objects); - ArgumentNullException.ThrowIfNull (keys); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); + if (!ValidateFromObjectsAndKeys (objects, keys)) + return new NSMutableDictionary (); - using (var no = NSArray.FromObjects (objects)) - using (var nk = NSArray.FromObjects (keys)) - return GenericFromObjectsAndKeysInternal (no, nk); + return FromObjectsAndKeys (objects, keys, objects.Length); } /// @@ -322,15 +310,11 @@ public TValue? this [TKey index] { /// A new mutable dictionary containing the specified key-value pairs. public static NSMutableDictionary? FromObjectsAndKeys (NSObject [] objects, NSObject [] keys, nint count) { - ArgumentNullException.ThrowIfNull (objects); - ArgumentNullException.ThrowIfNull (keys); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - if (count < 1 || objects.Length < count || keys.Length < count) - throw new ArgumentException (nameof (count)); + if (!ValidateFromObjectsAndKeys (objects, keys, count)) + return new NSMutableDictionary (); - using (var no = NSArray.FromNSObjects (objects)) - using (var nk = NSArray.FromNSObjects (keys)) + using (var no = NSArray.FromNativeObjects (objects, count)) + using (var nk = NSArray.FromNativeObjects (keys, count)) return GenericFromObjectsAndKeysInternal (no, nk); } @@ -343,15 +327,11 @@ public TValue? this [TKey index] { /// A new mutable dictionary containing the specified key-value pairs. public static NSMutableDictionary? FromObjectsAndKeys (object [] objects, object [] keys, nint count) { - ArgumentNullException.ThrowIfNull (objects); - ArgumentNullException.ThrowIfNull (keys); - if (objects.Length != keys.Length) - throw new ArgumentException (nameof (objects) + " and " + nameof (keys) + " arrays have different sizes"); - if (count < 1 || objects.Length < count || keys.Length < count) - throw new ArgumentException (nameof (count)); + if (!ValidateFromObjectsAndKeys (objects, keys, count)) + return new NSMutableDictionary (); - using (var no = NSArray.FromObjects (objects)) - using (var nk = NSArray.FromObjects (keys)) + using (var no = NSArray.FromObjects (count, objects)) + using (var nk = NSArray.FromObjects (count, keys)) return GenericFromObjectsAndKeysInternal (no, nk); } diff --git a/tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-preservedapis.txt b/tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-preservedapis.txt index 18e5d5f632b3..7e67679fb9e1 100644 --- a/tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-preservedapis.txt +++ b/tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-preservedapis.txt @@ -78,7 +78,7 @@ Microsoft.iOS.dll:Foundation.NSComparisonResult Foundation.NSComparisonResult::A Microsoft.iOS.dll:Foundation.NSComparisonResult Foundation.NSComparisonResult::Descending Microsoft.iOS.dll:Foundation.NSComparisonResult Foundation.NSComparisonResult::Same Microsoft.iOS.dll:Foundation.NSDictionary -Microsoft.iOS.dll:Foundation.NSDictionary Foundation.NSDictionary/d__64::<>4__this +Microsoft.iOS.dll:Foundation.NSDictionary Foundation.NSDictionary/d__66::<>4__this Microsoft.iOS.dll:Foundation.NSDictionary._Xamarin_ConstructINativeObject(ObjCRuntime.NativeHandle, System.Boolean) Microsoft.iOS.dll:Foundation.NSDictionary._Xamarin_ConstructNSObject(ObjCRuntime.NativeHandle) Microsoft.iOS.dll:Foundation.NSDictionary..cctor() @@ -91,11 +91,11 @@ Microsoft.iOS.dll:Foundation.NSDictionary.GetEnumerator() Microsoft.iOS.dll:Foundation.NSDictionary.ObjectForKey(Foundation.NSObject) Microsoft.iOS.dll:Foundation.NSDictionary.System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair`2[], System.Int32) Microsoft.iOS.dll:Foundation.NSDictionary.System.Collections.Generic.ICollection>.get_Count() -Microsoft.iOS.dll:Foundation.NSDictionary/d__64 -Microsoft.iOS.dll:Foundation.NSDictionary/d__64..ctor(System.Int32) -Microsoft.iOS.dll:Foundation.NSDictionary/d__64.MoveNext() -Microsoft.iOS.dll:Foundation.NSDictionary/d__64.System.Collections.Generic.IEnumerator>.get_Current() -Microsoft.iOS.dll:Foundation.NSDictionary/d__64.System.IDisposable.Dispose() +Microsoft.iOS.dll:Foundation.NSDictionary/d__66 +Microsoft.iOS.dll:Foundation.NSDictionary/d__66..ctor(System.Int32) +Microsoft.iOS.dll:Foundation.NSDictionary/d__66.MoveNext() +Microsoft.iOS.dll:Foundation.NSDictionary/d__66.System.Collections.Generic.IEnumerator>.get_Current() +Microsoft.iOS.dll:Foundation.NSDictionary/d__66.System.IDisposable.Dispose() Microsoft.iOS.dll:Foundation.NSException Microsoft.iOS.dll:Foundation.NSException ObjCRuntime.MarshalObjectiveCExceptionEventArgs::k__BackingField Microsoft.iOS.dll:Foundation.NSException ObjCRuntime.MarshalObjectiveCExceptionEventArgs::Exception() @@ -166,7 +166,7 @@ Microsoft.iOS.dll:Foundation.NSObject.ToString() Microsoft.iOS.dll:Foundation.NSObject.xamarin_release_managed_ref(System.IntPtr, System.Byte) Microsoft.iOS.dll:Foundation.NSObject.xamarin_set_gchandle_with_flags_safe(System.IntPtr, System.IntPtr, Foundation.NSObject/XamarinGCHandleFlags, System.IntPtr) Microsoft.iOS.dll:Foundation.NSObject[] Foundation.NSDictionary::Keys() -Microsoft.iOS.dll:Foundation.NSObject[] Foundation.NSDictionary/d__64::<>7__wrap1 +Microsoft.iOS.dll:Foundation.NSObject[] Foundation.NSDictionary/d__66::<>7__wrap1 Microsoft.iOS.dll:Foundation.NSObject/Flags Microsoft.iOS.dll:Foundation.NSObject/Flags Foundation.NSObject::flags() Microsoft.iOS.dll:Foundation.NSObject/Flags Foundation.NSObject/Flags::Disposed @@ -1280,8 +1280,8 @@ Microsoft.iOS.dll:System.Collections.Generic.Dictionary`2 ObjCRuntime.Runtime::intptr_bool_ctor_cache Microsoft.iOS.dll:System.Collections.Generic.Dictionary`2 ObjCRuntime.Runtime::intptr_ctor_cache Microsoft.iOS.dll:System.Collections.Generic.Dictionary`2 ObjCRuntime.Class::token_to_member -Microsoft.iOS.dll:System.Collections.Generic.KeyValuePair`2 Foundation.NSDictionary/d__64::<>2__current -Microsoft.iOS.dll:System.Collections.Generic.KeyValuePair`2 Foundation.NSDictionary/d__64::System.Collections.Generic.IEnumerator>.Current() +Microsoft.iOS.dll:System.Collections.Generic.KeyValuePair`2 Foundation.NSDictionary/d__66::<>2__current +Microsoft.iOS.dll:System.Collections.Generic.KeyValuePair`2 Foundation.NSDictionary/d__66::System.Collections.Generic.IEnumerator>.Current() Microsoft.iOS.dll:System.Collections.Generic.List`1 Foundation.NSObject/NSObject_Disposer::drainList1 Microsoft.iOS.dll:System.Collections.Generic.List`1 Foundation.NSObject/NSObject_Disposer::drainList2 Microsoft.iOS.dll:System.Collections.Generic.List`1 Foundation.NSObject/NSObject_Disposer::handles @@ -1294,8 +1294,8 @@ Microsoft.iOS.dll:System.Exception ObjCRuntime.MarshalManagedExceptionEventArgs: Microsoft.iOS.dll:System.Func`2 CoreFoundation.CFArray/<>O::<0>__FromHandle Microsoft.iOS.dll:System.Func`2 CoreFoundation.CFArray/O__24_0`1::<0>__DefaultConvert Microsoft.iOS.dll:System.Int32 Foundation.NSDictionary::System.Collections.Generic.ICollection>.Count() -Microsoft.iOS.dll:System.Int32 Foundation.NSDictionary/d__64::<>1__state -Microsoft.iOS.dll:System.Int32 Foundation.NSDictionary/d__64::<>7__wrap2 +Microsoft.iOS.dll:System.Int32 Foundation.NSDictionary/d__66::<>1__state +Microsoft.iOS.dll:System.Int32 Foundation.NSDictionary/d__66::<>7__wrap2 Microsoft.iOS.dll:System.Int32 Foundation.NSObjectFlag::value__ Microsoft.iOS.dll:System.Int32 ObjCRuntime.Arch::value__ Microsoft.iOS.dll:System.Int32 ObjCRuntime.ArgumentSemantic::value__ diff --git a/tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-size.txt b/tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-size.txt index 7bb88c521706..6d966d8a337b 100644 --- a/tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-size.txt +++ b/tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-size.txt @@ -1,9 +1,9 @@ -AppBundleSize: 3,610,430 bytes (3,525.8 KB = 3.4 MB) +AppBundleSize: 3,611,965 bytes (3,527.3 KB = 3.4 MB) # The following list of files and their sizes is just informational / for review, and isn't used in the test: _CodeSignature/CodeResources: 3,997 bytes (3.9 KB = 0.0 MB) archived-expanded-entitlements.xcent: 384 bytes (0.4 KB = 0.0 MB) -Info.plist: 1,164 bytes (1.1 KB = 0.0 MB) -Microsoft.iOS.dll: 149,504 bytes (146.0 KB = 0.1 MB) +Info.plist: 1,163 bytes (1.1 KB = 0.0 MB) +Microsoft.iOS.dll: 151,040 bytes (147.5 KB = 0.1 MB) PkgInfo: 8 bytes (0.0 KB = 0.0 MB) runtimeconfig.bin: 1,405 bytes (1.4 KB = 0.0 MB) SizeTestApp: 2,404,544 bytes (2,348.2 KB = 2.3 MB) diff --git a/tests/dotnet/UnitTests/expected/iOS-MonoVM-preservedapis.txt b/tests/dotnet/UnitTests/expected/iOS-MonoVM-preservedapis.txt index c556bdf846d3..16dacc410d61 100644 --- a/tests/dotnet/UnitTests/expected/iOS-MonoVM-preservedapis.txt +++ b/tests/dotnet/UnitTests/expected/iOS-MonoVM-preservedapis.txt @@ -62,7 +62,7 @@ Microsoft.iOS.dll:Foundation.NSAutoreleasePool..ctor() Microsoft.iOS.dll:Foundation.NSAutoreleasePool..ctor(ObjCRuntime.NativeHandle) Microsoft.iOS.dll:Foundation.NSAutoreleasePool.get_ClassHandle() Microsoft.iOS.dll:Foundation.NSDictionary -Microsoft.iOS.dll:Foundation.NSDictionary Foundation.NSDictionary/d__64::<>4__this +Microsoft.iOS.dll:Foundation.NSDictionary Foundation.NSDictionary/d__66::<>4__this Microsoft.iOS.dll:Foundation.NSDictionary._Xamarin_ConstructINativeObject(ObjCRuntime.NativeHandle, System.Boolean) Microsoft.iOS.dll:Foundation.NSDictionary._Xamarin_ConstructNSObject(ObjCRuntime.NativeHandle) Microsoft.iOS.dll:Foundation.NSDictionary..cctor() @@ -75,11 +75,11 @@ Microsoft.iOS.dll:Foundation.NSDictionary.GetEnumerator() Microsoft.iOS.dll:Foundation.NSDictionary.ObjectForKey(Foundation.NSObject) Microsoft.iOS.dll:Foundation.NSDictionary.System.Collections.Generic.ICollection>.CopyTo(System.Collections.Generic.KeyValuePair`2[], System.Int32) Microsoft.iOS.dll:Foundation.NSDictionary.System.Collections.Generic.ICollection>.get_Count() -Microsoft.iOS.dll:Foundation.NSDictionary/d__64 -Microsoft.iOS.dll:Foundation.NSDictionary/d__64..ctor(System.Int32) -Microsoft.iOS.dll:Foundation.NSDictionary/d__64.MoveNext() -Microsoft.iOS.dll:Foundation.NSDictionary/d__64.System.Collections.Generic.IEnumerator>.get_Current() -Microsoft.iOS.dll:Foundation.NSDictionary/d__64.System.IDisposable.Dispose() +Microsoft.iOS.dll:Foundation.NSDictionary/d__66 +Microsoft.iOS.dll:Foundation.NSDictionary/d__66..ctor(System.Int32) +Microsoft.iOS.dll:Foundation.NSDictionary/d__66.MoveNext() +Microsoft.iOS.dll:Foundation.NSDictionary/d__66.System.Collections.Generic.IEnumerator>.get_Current() +Microsoft.iOS.dll:Foundation.NSDictionary/d__66.System.IDisposable.Dispose() Microsoft.iOS.dll:Foundation.NSException Microsoft.iOS.dll:Foundation.NSException ObjCRuntime.MarshalObjectiveCExceptionEventArgs::k__BackingField Microsoft.iOS.dll:Foundation.NSException ObjCRuntime.MarshalObjectiveCExceptionEventArgs::Exception() @@ -148,7 +148,7 @@ Microsoft.iOS.dll:Foundation.NSObject.ToString() Microsoft.iOS.dll:Foundation.NSObject.xamarin_release_managed_ref(System.IntPtr, System.Byte) Microsoft.iOS.dll:Foundation.NSObject.xamarin_set_gchandle_with_flags_safe(System.IntPtr, System.IntPtr, Foundation.NSObject/XamarinGCHandleFlags, System.IntPtr) Microsoft.iOS.dll:Foundation.NSObject[] Foundation.NSDictionary::Keys() -Microsoft.iOS.dll:Foundation.NSObject[] Foundation.NSDictionary/d__64::<>7__wrap1 +Microsoft.iOS.dll:Foundation.NSObject[] Foundation.NSDictionary/d__66::<>7__wrap1 Microsoft.iOS.dll:Foundation.NSObject/Flags Microsoft.iOS.dll:Foundation.NSObject/Flags Foundation.NSObject::flags() Microsoft.iOS.dll:Foundation.NSObject/Flags Foundation.NSObject/Flags::Disposed @@ -683,8 +683,8 @@ Microsoft.iOS.dll:System.Collections.Generic.Dictionary`2 ObjCRuntime.Runtime::intptr_bool_ctor_cache Microsoft.iOS.dll:System.Collections.Generic.Dictionary`2 ObjCRuntime.Runtime::intptr_ctor_cache Microsoft.iOS.dll:System.Collections.Generic.Dictionary`2 ObjCRuntime.Class::token_to_member -Microsoft.iOS.dll:System.Collections.Generic.KeyValuePair`2 Foundation.NSDictionary/d__64::<>2__current -Microsoft.iOS.dll:System.Collections.Generic.KeyValuePair`2 Foundation.NSDictionary/d__64::System.Collections.Generic.IEnumerator>.Current() +Microsoft.iOS.dll:System.Collections.Generic.KeyValuePair`2 Foundation.NSDictionary/d__66::<>2__current +Microsoft.iOS.dll:System.Collections.Generic.KeyValuePair`2 Foundation.NSDictionary/d__66::System.Collections.Generic.IEnumerator>.Current() Microsoft.iOS.dll:System.Collections.Generic.List`1 Foundation.NSObject/NSObject_Disposer::drainList1 Microsoft.iOS.dll:System.Collections.Generic.List`1 Foundation.NSObject/NSObject_Disposer::drainList2 Microsoft.iOS.dll:System.Collections.Generic.List`1 Foundation.NSObject/NSObject_Disposer::handles @@ -694,8 +694,8 @@ Microsoft.iOS.dll:System.Exception ObjCRuntime.MarshalManagedExceptionEventArgs: Microsoft.iOS.dll:System.Func`2 CoreFoundation.CFArray/<>O::<0>__FromHandle Microsoft.iOS.dll:System.Func`2 CoreFoundation.CFArray/O__24_0`1::<0>__DefaultConvert Microsoft.iOS.dll:System.Int32 Foundation.NSDictionary::System.Collections.Generic.ICollection>.Count() -Microsoft.iOS.dll:System.Int32 Foundation.NSDictionary/d__64::<>1__state -Microsoft.iOS.dll:System.Int32 Foundation.NSDictionary/d__64::<>7__wrap2 +Microsoft.iOS.dll:System.Int32 Foundation.NSDictionary/d__66::<>1__state +Microsoft.iOS.dll:System.Int32 Foundation.NSDictionary/d__66::<>7__wrap2 Microsoft.iOS.dll:System.Int32 Foundation.NSObjectFlag::value__ Microsoft.iOS.dll:System.Int32 ObjCRuntime.Arch::value__ Microsoft.iOS.dll:System.Int32 ObjCRuntime.ArgumentSemantic::value__ diff --git a/tests/dotnet/UnitTests/expected/iOS-MonoVM-size.txt b/tests/dotnet/UnitTests/expected/iOS-MonoVM-size.txt index ba6711914953..e9b92899cb31 100644 --- a/tests/dotnet/UnitTests/expected/iOS-MonoVM-size.txt +++ b/tests/dotnet/UnitTests/expected/iOS-MonoVM-size.txt @@ -1,14 +1,14 @@ -AppBundleSize: 9,357,320 bytes (9,138.0 KB = 8.9 MB) +AppBundleSize: 9,362,185 bytes (9,142.8 KB = 8.9 MB) # The following list of files and their sizes is just informational / for review, and isn't used in the test: _CodeSignature/CodeResources: 5,229 bytes (5.1 KB = 0.0 MB) aot-instances.aotdata.arm64: 827,592 bytes (808.2 KB = 0.8 MB) archived-expanded-entitlements.xcent: 384 bytes (0.4 KB = 0.0 MB) -Info.plist: 1,138 bytes (1.1 KB = 0.0 MB) -Microsoft.iOS.aotdata.arm64: 22,832 bytes (22.3 KB = 0.0 MB) -Microsoft.iOS.dll: 47,616 bytes (46.5 KB = 0.0 MB) +Info.plist: 1,163 bytes (1.1 KB = 0.0 MB) +Microsoft.iOS.aotdata.arm64: 22,872 bytes (22.3 KB = 0.0 MB) +Microsoft.iOS.dll: 48,640 bytes (47.5 KB = 0.0 MB) PkgInfo: 8 bytes (0.0 KB = 0.0 MB) runtimeconfig.bin: 1,481 bytes (1.4 KB = 0.0 MB) -SizeTestApp: 7,256,864 bytes (7,086.8 KB = 6.9 MB) +SizeTestApp: 7,260,640 bytes (7,090.5 KB = 6.9 MB) SizeTestApp.aotdata.arm64: 1,456 bytes (1.4 KB = 0.0 MB) SizeTestApp.dll: 7,168 bytes (7.0 KB = 0.0 MB) System.Private.CoreLib.aotdata.arm64: 640,736 bytes (625.7 KB = 0.6 MB) diff --git a/tests/dotnet/UnitTests/expected/iOS-NativeAOT-size.txt b/tests/dotnet/UnitTests/expected/iOS-NativeAOT-size.txt index fc32a822989c..3735c88837b0 100644 --- a/tests/dotnet/UnitTests/expected/iOS-NativeAOT-size.txt +++ b/tests/dotnet/UnitTests/expected/iOS-NativeAOT-size.txt @@ -1,8 +1,8 @@ -AppBundleSize: 2,450,623 bytes (2,393.2 KB = 2.3 MB) +AppBundleSize: 2,450,656 bytes (2,393.2 KB = 2.3 MB) # The following list of files and their sizes is just informational / for review, and isn't used in the test: _CodeSignature/CodeResources: 2,589 bytes (2.5 KB = 0.0 MB) archived-expanded-entitlements.xcent: 384 bytes (0.4 KB = 0.0 MB) -Info.plist: 1,130 bytes (1.1 KB = 0.0 MB) +Info.plist: 1,163 bytes (1.1 KB = 0.0 MB) PkgInfo: 8 bytes (0.0 KB = 0.0 MB) runtimeconfig.bin: 1,808 bytes (1.8 KB = 0.0 MB) SizeTestApp: 2,444,704 bytes (2,387.4 KB = 2.3 MB) diff --git a/tests/monotouch-test/Foundation/NSDictionary2Test.cs b/tests/monotouch-test/Foundation/NSDictionary2Test.cs index ee55050bc907..e4c00e3fdea6 100644 --- a/tests/monotouch-test/Foundation/NSDictionary2Test.cs +++ b/tests/monotouch-test/Foundation/NSDictionary2Test.cs @@ -40,6 +40,17 @@ public void Ctor_Arrays () Assert.AreEqual ((string) (j [(NSString) "second-k"]), "second", "lookup2"); } + [Test] + public void Ctor_WithNullValue () + { + var key = (NSString) "key"; + var dict = new NSDictionary (key, null); + Assert.AreEqual ((nuint) 1, dict.Count, "count"); + var baseDict = (NSDictionary) dict; + var rawValue = baseDict.ObjectForKey (key); + Assert.IsInstanceOf (rawValue, "Null value should be NSNull"); + } + [Test] public void Ctor_NSDictionary () { diff --git a/tests/monotouch-test/Foundation/NSDictionaryTest.cs b/tests/monotouch-test/Foundation/NSDictionaryTest.cs index 57764bc937aa..cd738779b9b9 100644 --- a/tests/monotouch-test/Foundation/NSDictionaryTest.cs +++ b/tests/monotouch-test/Foundation/NSDictionaryTest.cs @@ -178,6 +178,26 @@ public void FromObjectsAndKeysTest_NullValue_NoCount () Assert.AreEqual (4, ((NSNumber) ns [new NSNumber (3)]).Int32Value, "Value 3"); } + [Test] + public void DictionaryCtorKeyValues_WithNull () + { + var key1 = new NSString ("key1"); + var key2 = new NSString ("key2"); + var value = new NSString ("value"); + + // Test null value + var dict = new NSDictionary (key1, null); + Assert.AreEqual ((nuint) 1, dict.Count, "count with null value"); + var rawValue = dict.ObjectForKey (key1); + Assert.IsInstanceOf (rawValue, "Null value should be NSNull"); + + // Test null in variadic args (value position) + dict = new NSDictionary (key1, value, key2, null); + Assert.AreEqual ((nuint) 2, dict.Count, "count with null in args"); + rawValue = dict.ObjectForKey (key2); + Assert.IsInstanceOf (rawValue, "Null value in args should be NSNull"); + } + [Test] public void Copy () { diff --git a/tests/monotouch-test/Foundation/NSMutableDictionary2Test.cs b/tests/monotouch-test/Foundation/NSMutableDictionary2Test.cs index 945c1c4d4e4b..0228b34d4ea7 100644 --- a/tests/monotouch-test/Foundation/NSMutableDictionary2Test.cs +++ b/tests/monotouch-test/Foundation/NSMutableDictionary2Test.cs @@ -61,6 +61,151 @@ public void FromObjectsAndKeysGenericTest () Assert.AreEqual (dict [keys [i]], values [i], $"key lookup, Iteration: {i}"); } + [Test] + public void Ctor_WithNullValue () + { + var key = (NSString) "key"; + using (var dict = new NSMutableDictionary (key, null)) { + Assert.AreEqual ((nuint) 1, dict.Count, "count"); + var baseDict = (NSDictionary) dict; + var rawValue = baseDict.ObjectForKey (key); + Assert.IsInstanceOf (rawValue, "Null value should be NSNull"); + } + } + + [Test] + public void FromObjectsAndKeys_Generic_WithNull () + { + var keys = new NSString [] { (NSString) "key1", (NSString) "key2" }; + var values = new NSString? [] { (NSString) "value1", null }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (values, keys)) { + Assert.IsNotNull (dict, "Dictionary should not be null"); + Assert.AreEqual ((nuint) 2, dict!.Count, "Count"); + Assert.AreEqual ("value1", dict [keys [0]].ToString (), "First value"); + var baseDict = (NSDictionary) dict; + var rawValue = baseDict.ObjectForKey (keys [1]); + Assert.IsInstanceOf (rawValue, "Null value should be NSNull"); + } + } + + [Test] + public void FromObjectsAndKeys_Generic_WithCount_WithNull () + { + var keys = new NSString [] { (NSString) "key1", (NSString) "key2", (NSString) "key3" }; + var values = new NSString? [] { (NSString) "value1", null, (NSString) "value3" }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (values, keys, 2)) { + Assert.IsNotNull (dict, "Dictionary should not be null"); + Assert.AreEqual ((nuint) 2, dict!.Count, "Count"); + Assert.AreEqual ("value1", dict [keys [0]].ToString (), "First value"); + var baseDict = (NSDictionary) dict; + var rawValue = baseDict.ObjectForKey (keys [1]); + Assert.IsInstanceOf (rawValue, "Null value should be NSNull"); + } + } + + [Test] + public void FromObjectsAndKeys_Object_WithCount () + { + var keys = new object [] { "key1", "key2", "key3" }; + var objs = new object [] { "value1", "value2", "value3" }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (objs, keys, 2)) { + Assert.IsNotNull (dict, "Dictionary should not be null"); + Assert.AreEqual ((nuint) 2, dict!.Count, "Count"); + Assert.AreEqual ("value1", dict [(NSString) "key1"].ToString (), "First value"); + Assert.AreEqual ("value2", dict [(NSString) "key2"].ToString (), "Second value"); + } + } + + [Test] + public void FromObjectsAndKeys_NSObject_WithCount_WithNull () + { + var keys = new NSObject [] { new NSString ("key1"), new NSString ("key2"), new NSString ("key3") }; + var objs = new NSObject? [] { new NSString ("value1"), null, new NSString ("value3") }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (objs, keys, 2)) { + Assert.IsNotNull (dict, "Dictionary should not be null"); + Assert.AreEqual ((nuint) 2, dict!.Count, "Count"); + Assert.AreEqual ("value1", dict [(NSString) keys [0]].ToString (), "First value"); + var baseDict = (NSDictionary) dict; + var rawValue = baseDict.ObjectForKey (keys [1]); + Assert.IsInstanceOf (rawValue, "Null value should be NSNull"); + } + } + + [Test] + public void FromObjectsAndKeys_NSObject_WithCount () + { + var keys = new NSObject [] { new NSString ("key1"), new NSString ("key2"), new NSString ("key3") }; + var objs = new NSObject [] { new NSString ("value1"), new NSString ("value2"), new NSString ("value3") }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (objs, keys, 2)) { + Assert.IsNotNull (dict, "Dictionary should not be null"); + Assert.AreEqual ((nuint) 2, dict!.Count, "Count"); + Assert.AreEqual ("value1", dict [(NSString) keys [0]].ToString (), "First value"); + Assert.AreEqual ("value2", dict [(NSString) keys [1]].ToString (), "Second value"); + } + } + + [Test] + public void FromObjectsAndKeys_Generic_WithCountZero () + { + var keys = new NSString [] { (NSString) "key1", (NSString) "key2" }; + var values = new NSString [] { (NSString) "value1", (NSString) "value2" }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (values, keys, 0)) { + Assert.IsNotNull (dict, "Dictionary should not be null"); + Assert.AreEqual ((nuint) 0, dict!.Count, "Count should be 0"); + } + } + + [Test] + public void FromObjectsAndKeys_DifferentArrayLengths_WithCount () + { + var keys = new NSString [] { (NSString) "key1", (NSString) "key2" }; + var values = new NSString [] { (NSString) "value1", (NSString) "value2", (NSString) "value3", (NSString) "value4" }; + + // Should work fine since we only use first 2 items from each array + using (var dict = NSMutableDictionary.FromObjectsAndKeys (values, keys, 2)) { + Assert.IsNotNull (dict, "Dictionary should not be null"); + Assert.AreEqual ((nuint) 2, dict!.Count, "Count"); + Assert.AreEqual ("value1", dict [keys [0]].ToString (), "First value"); + Assert.AreEqual ("value2", dict [keys [1]].ToString (), "Second value"); + } + } + + [Test] + public void FromObjectsAndKeys_CountLargerThanKeys () + { + var keys = new NSString [] { (NSString) "key1", (NSString) "key2" }; + var values = new NSString [] { (NSString) "value1", (NSString) "value2", (NSString) "value3" }; + + // Should throw because count > keys.Length + Assert.Throws (() => NSMutableDictionary.FromObjectsAndKeys (values, keys, 3), "Should throw when count > keys.Length"); + } + + [Test] + public void FromObjectsAndKeys_CountLargerThanValues () + { + var keys = new NSString [] { (NSString) "key1", (NSString) "key2", (NSString) "key3" }; + var values = new NSString [] { (NSString) "value1", (NSString) "value2" }; + + // Should throw because count > values.Length + Assert.Throws (() => NSMutableDictionary.FromObjectsAndKeys (values, keys, 3), "Should throw when count > values.Length"); + } + + [Test] + public void FromObjectsAndKeys_NegativeCount () + { + var keys = new NSString [] { (NSString) "key1", (NSString) "key2" }; + var values = new NSString [] { (NSString) "value1", (NSString) "value2" }; + + // Should throw for negative count + Assert.Throws (() => NSMutableDictionary.FromObjectsAndKeys (values, keys, -1), "Should throw for negative count"); + } + [Test] public void KeyValue_Autorelease () { diff --git a/tests/monotouch-test/Foundation/NSMutableDictionaryTest.cs b/tests/monotouch-test/Foundation/NSMutableDictionaryTest.cs index af0c20d3d162..fa772dce2fdb 100644 --- a/tests/monotouch-test/Foundation/NSMutableDictionaryTest.cs +++ b/tests/monotouch-test/Foundation/NSMutableDictionaryTest.cs @@ -204,5 +204,112 @@ public void MissingKey_IDictionaryContains () Assert.IsTrue (idict.Contains ((NSString) "existingKey"), "Contains should return true for existing key"); } } + + [Test] + public void FromObjectsAndKeys_WithNull () + { + var keys = new NSObject [] { new NSString ("key1"), new NSString ("key2") }; + var objs = new NSObject? [] { new NSString ("value1"), null }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (objs, keys)) { + Assert.AreEqual ((nuint) 2, dict.Count, "Count"); + Assert.AreEqual ("value1", dict [keys [0]].ToString (), "First value"); + Assert.IsInstanceOf (dict [keys [1]], "Null value should be NSNull"); + } + } + + [Test] + public void FromObjectsAndKeys_NSObject_WithCount_WithNull () + { + var keys = new NSObject [] { new NSString ("key1"), new NSString ("key2"), new NSString ("key3") }; + var objs = new NSObject? [] { new NSString ("value1"), null, new NSString ("value3") }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (objs, keys, 2)) { + Assert.AreEqual ((nuint) 2, dict.Count, "Count"); + Assert.AreEqual ("value1", dict [keys [0]].ToString (), "First value"); + Assert.IsInstanceOf (dict [keys [1]], "Null value should be NSNull"); + } + } + + [Test] + public void FromObjectsAndKeys_NSObject_WithCount () + { + var keys = new NSObject [] { new NSString ("key1"), new NSString ("key2"), new NSString ("key3") }; + var objs = new NSObject [] { new NSString ("value1"), new NSString ("value2"), new NSString ("value3") }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (objs, keys, 2)) { + Assert.AreEqual ((nuint) 2, dict.Count, "Count"); + Assert.AreEqual ("value1", dict [keys [0]].ToString (), "First value"); + Assert.AreEqual ("value2", dict [keys [1]].ToString (), "Second value"); + } + } + + [Test] + public void FromObjectsAndKeys_NSObject_WithCountZero () + { + var keys = new NSObject [] { new NSString ("key1"), new NSString ("key2") }; + var objs = new NSObject [] { new NSString ("value1"), new NSString ("value2") }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (objs, keys, 0)) { + Assert.AreEqual ((nuint) 0, dict.Count, "Count should be 0"); + } + } + + [Test] + public void FromObjectsAndKeys_Object_WithCount_WithNull () + { + var keys = new object [] { "key1", "key2", "key3" }; + var objs = new object [] { "value1", "value2", "value3" }; + + using (var dict = NSMutableDictionary.FromObjectsAndKeys (objs, keys, 2)) { + Assert.AreEqual ((nuint) 2, dict.Count, "Count"); + Assert.AreEqual ("value1", dict [(NSString) "key1"].ToString (), "First value"); + Assert.AreEqual ("value2", dict [(NSString) "key2"].ToString (), "Second value"); + } + } + + [Test] + public void FromObjectsAndKeys_DifferentArrayLengths_WithCount () + { + var keys = new NSObject [] { new NSString ("key1"), new NSString ("key2") }; + var objs = new NSObject [] { new NSString ("value1"), new NSString ("value2"), new NSString ("value3"), new NSString ("value4") }; + + // Should work fine since we only use first 2 items from each array + using (var dict = NSMutableDictionary.FromObjectsAndKeys (objs, keys, 2)) { + Assert.AreEqual ((nuint) 2, dict.Count, "Count"); + Assert.AreEqual ("value1", dict [keys [0]].ToString (), "First value"); + Assert.AreEqual ("value2", dict [keys [1]].ToString (), "Second value"); + } + } + + [Test] + public void FromObjectsAndKeys_CountLargerThanKeys () + { + var keys = new NSObject [] { new NSString ("key1"), new NSString ("key2") }; + var objs = new NSObject [] { new NSString ("value1"), new NSString ("value2"), new NSString ("value3") }; + + // Should throw because count > keys.Length + Assert.Throws (() => NSMutableDictionary.FromObjectsAndKeys (objs, keys, 3), "Should throw when count > keys.Length"); + } + + [Test] + public void FromObjectsAndKeys_CountLargerThanObjects () + { + var keys = new NSObject [] { new NSString ("key1"), new NSString ("key2"), new NSString ("key3") }; + var objs = new NSObject [] { new NSString ("value1"), new NSString ("value2") }; + + // Should throw because count > objs.Length + Assert.Throws (() => NSMutableDictionary.FromObjectsAndKeys (objs, keys, 3), "Should throw when count > objs.Length"); + } + + [Test] + public void FromObjectsAndKeys_NegativeCount () + { + var keys = new NSObject [] { new NSString ("key1"), new NSString ("key2") }; + var objs = new NSObject [] { new NSString ("value1"), new NSString ("value2") }; + + // Should throw for negative count + Assert.Throws (() => NSMutableDictionary.FromObjectsAndKeys (objs, keys, -1), "Should throw for negative count"); + } } }