<PackageReference Include="NUnit" Version="3.10.0" />

UniqueItemsConstraint

UniqueItemsConstraint tests whether all the items in a collection are unique.
using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Reflection; namespace NUnit.Framework.Constraints { public class UniqueItemsConstraint : CollectionItemsEqualConstraint { private static readonly MethodInfo ItemsUniqueMethod = typeof(UniqueItemsConstraint).GetMethod("ItemsUnique", BindingFlags.Static | BindingFlags.NonPublic); public override string Description => "all items unique"; protected override bool Matches(IEnumerable actual) { return TryFastAlgorithm(actual) ?? OriginalAlgorithm(actual); } private bool OriginalAlgorithm(IEnumerable actual) { List<object> list = new List<object>(); foreach (object item in actual) { foreach (object item2 in list) { if (ItemsEqual(item, item2)) return false; } list.Add(item); } return true; } private bool? TryFastAlgorithm(IEnumerable actual) { if (base.UsingExternalComparer) return null; Type genericTypeArgument = GetGenericTypeArgument(actual); if (genericTypeArgument == (Type)null || !IsSealed(genericTypeArgument) || IsHandledSpeciallyByNUnit(genericTypeArgument)) return null; if (base.IgnoringCase) { if (genericTypeArgument == typeof(string)) return StringsUniqueIgnoringCase((IEnumerable<string>)actual); if (genericTypeArgument == typeof(char)) return CharsUniqueIgnoringCase((IEnumerable<char>)actual); } return (bool)ItemsUniqueMethod.MakeGenericMethod(genericTypeArgument).Invoke(null, new object[1] { actual }); } private bool IsSealed(Type type) { return type.GetTypeInfo().IsSealed; } private static bool ItemsUnique<T>(IEnumerable<T> actual) { HashSet<T> hashSet = new HashSet<T>(); foreach (T item in actual) { if (!hashSet.Add(item)) return false; } return true; } private static bool StringsUniqueIgnoringCase(IEnumerable<string> actual) { HashSet<string> hashSet = new HashSet<string>(); foreach (string item2 in actual) { string item = item2.ToLower(); if (!hashSet.Add(item)) return false; } return true; } private static bool CharsUniqueIgnoringCase(IEnumerable<char> actual) { HashSet<char> hashSet = new HashSet<char>(); foreach (char item2 in actual) { char item = char.ToLower(item2); if (!hashSet.Add(item)) return false; } return true; } private static bool IsHandledSpeciallyByNUnit(Type type) { if (type == typeof(string)) return false; if (!type.IsArray && !typeof(IEnumerable).IsAssignableFrom(type) && !typeof(Stream).IsAssignableFrom(type) && !typeof(DirectoryInfo).IsAssignableFrom(type) && !(type.FullName == "System.Tuple")) return type.FullName == "System.ValueTuple"; return true; } private Type GetGenericTypeArgument(IEnumerable actual) { Type[] interfaces = actual.GetType().GetInterfaces(); foreach (Type type in interfaces) { if (type.FullName.StartsWith("System.Collections.Generic.IEnumerable`1")) return type.GenericTypeArguments[0]; } return null; } } }