using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Text; namespace ScreenConnect; public static class EnumerableExtensions { public static IEnumerable AppendIf(this IEnumerable @this, T newItem, bool append) { foreach (T item in @this) { yield return item; } if (append) { yield return newItem; } } public static IEnumerable AppendIf(this IEnumerable @this, Func newItemCreator, bool append) { foreach (T item in @this) { yield return item; } if (append) { yield return newItemCreator(); } } public static IEnumerable PrependIf(this IEnumerable @this, T newItem, bool prepend) { if (prepend) { yield return newItem; } foreach (T item in @this) { yield return item; } } public static IEnumerable PrependIf(this IEnumerable @this, Func newItemCreator, bool prepend) { if (prepend) { yield return newItemCreator(); } foreach (T item in @this) { yield return item; } } public static IEnumerable> WhereValueNotNull(this IEnumerable> @this) { return @this.Where>((KeyValuePair it) => it.Value != null); } public static IEnumerable TryAppend(this IEnumerable @this, Func newItemCreator) where T : class { foreach (T item in @this) { yield return item; } T val = Extensions.TryGet(newItemCreator); if (val != null) { yield return val; } } public static IEnumerable AppendIfNotNull(this IEnumerable @this, T? newItem) where T : class { return @this.AppendIfNotNull(newItem, (T it) => it); } public static IEnumerable AppendIfNotNull(this IEnumerable @this, T? newItem) where T : struct { foreach (T item in @this) { yield return item; } if (newItem.HasValue) { yield return newItem.Value; } } public static IEnumerable AppendIfNotNull(this IEnumerable @this, TItem? item, Func func) where TItem : class { foreach (T item2 in @this) { yield return item2; } if (item != null) { yield return func(item); } } public static IEnumerable PrependIfNotNull(this IEnumerable @this, T? newItem) where T : class { if (newItem != null) { yield return newItem; } foreach (T item in @this) { yield return item; } } public static IEnumerable Generate(int count, Func generator) { return from _ in Enumerable.Range(0, count) select generator(); } public static IEnumerable Generate(int count, Func generator) { return Enumerable.Range(0, count).Select(generator); } public static bool IsNullOrEmpty([NotNullWhen(false)] this IEnumerable? @this) { if (@this == null) { return true; } if (@this is ICollection collection) { return collection.Count == 0; } IEnumerator enumerator = @this.GetEnumerator(); try { if (enumerator.MoveNext()) { _ = enumerator.Current; return false; } } finally { IDisposable disposable = enumerator as IDisposable; if (disposable != null) { disposable.Dispose(); } } return true; } public static string Join(this IEnumerable @this, char separator) { return @this.Join(separator.ToString()); } public static string Join(this IEnumerable @this, string? separator) { StringBuilder stringBuilder = null; foreach (string item in @this) { if (stringBuilder == null) { stringBuilder = new StringBuilder(128); } else { stringBuilder.Append(separator); } stringBuilder.Append(item); } return stringBuilder?.ToString() ?? string.Empty; } public static void Join(this IEnumerable @this, string? separator, StringBuilder builder) { bool flag = true; foreach (string item in @this) { if (flag) { flag = false; } else { builder.Append(separator); } builder.Append(item); } } public static int Count(this IList @this, Func predicate) { int num = 0; for (int i = 0; i < @this.Count; i++) { if (predicate(@this[i])) { num++; } } return num; } public static IEnumerable MutateMany(this IEnumerable @this, Proc mutator) { return @this.Select((T it) => it.Mutate(mutator)); } public static TDictionary ToDictionary(this IEnumerable source, Func keySelector, Func valueSelector, bool throwOnDuplicateKey = true) where TKey : notnull where TDictionary : IDictionary, new() { TDictionary result = new TDictionary(); foreach (TSource item in source) { TKey val = keySelector(item); if (result.ContainsKey(val) & throwOnDuplicateKey) { throw new ArgumentException($"Duplicate key: {val}"); } result[val] = valueSelector(item); } return result; } public static Dictionary ToDictionary(this IEnumerable source, Func keySelector, Func valueSelector, bool throwOnDuplicateKey = true) where TKey : notnull { return source.ToDictionary>(keySelector, valueSelector, throwOnDuplicateKey); } public static Dictionary ToDictionary(this IEnumerable source, Func keySelector, bool throwOnDuplicateKey = true) where TKey : notnull { return source.ToDictionary>(keySelector, (TSource it) => it, throwOnDuplicateKey); } public static Dictionary> ToDictionary(this IEnumerable> groupings) where TKey : notnull { return groupings.ToDictionary((IGrouping it) => it.Key, (IGrouping it) => it.ToList()); } public static Dictionary ToDictionary(this IEnumerable<(TKey, TValue)> items) where TKey : notnull { return items.ToDictionary<(TKey, TValue), TKey, TValue>(((TKey, TValue) it) => it.Item1, ((TKey, TValue) it) => it.Item2); } public static IDictionary ToDictionary(this (TKey, TValue) tuple) where TKey : notnull { return new(TKey, TValue)[1] { tuple }.ToDictionary(); } public static string[] AllNonNullKeys(this NameValueCollection collection) { return collection.AllKeys.WhereNotNull().ToArray(); } public static Dictionary ToDictionary(this NameValueCollection collection) { return collection.AllNonNullKeys().ToDictionary((string it) => it, (string it) => collection[it].ToNullable()); } public static Dictionary ToDictionary(this NameValueCollection collection, bool throwOnDuplicateKey) { return collection.AllNonNullKeys().ToDictionary((string it) => it, (string it) => collection[it].ToNullable(), throwOnDuplicateKey); } public static Dictionary ToMultiValueDictionary(this NameValueCollection collection) { return collection.AllNonNullKeys().ToDictionary((string it) => it, (string it) => collection.GetValues(it).ToNullable()); } public static TDictionary ToDictionary(this IEnumerable> mappings, bool throwOnDuplicateKey = false) where TKey : notnull where TDictionary : IDictionary, new() { return mappings.ToDictionary, TKey, TValue, TDictionary>((KeyValuePair _) => _.Key, (KeyValuePair _) => _.Value, throwOnDuplicateKey); } public static Dictionary ToDictionary(this IEnumerable> mappings, bool throwOnDuplicateKey = false) where TKey : notnull { return mappings.ToDictionary>(throwOnDuplicateKey); } public static DisposableList ToDisposableList(this IEnumerable @this) where T : IDisposable { return new DisposableList(@this); } public static T? FirstOrDefault(this IEnumerable @this, out int index) { return @this.FirstOrDefault(null, out index); } public static T? FirstOrDefault(this IEnumerable @this, Predicate? predicate, out int index) { index = 0; foreach (T item in @this) { if (predicate == null || predicate(item)) { return item; } index++; } index = -1; return default(T); } public static TCollection ToCollection(this IEnumerable @this, Func factory) where TCollection : IList { TCollection result = factory(); foreach (T item in @this) { result.Add(item); } return result; } public static TCollection ToCollection(this IEnumerable @this) where TCollection : IList, new() { return @this.ToCollection(() => new TCollection()); } }