// TODO: Put strings into the resources. // public static Type GetIArgsTupleType(ArgumentUtilitiesHandle <IArgsTuple> hnd) { hnd.EnsureNotNull(); // var args = hnd.Value; if (args.ArgsCount < 1) { return(typeof(IArgsTuple)); } else { Type result; // switch (args.ArgsCount - 1) { case 0: result = typeof(IArgsTuple <>); break; case 1: result = typeof(IArgsTuple <,>); break; case 2: result = typeof(IArgsTuple <, ,>); break; case 3: result = typeof(IArgsTuple <, , ,>); break; case 4: result = typeof(IArgsTuple <, , , ,>); break; case 5: result = typeof(IArgsTuple <, , , , ,>); break; default: throw new ArgumentException(message: $"No generic-type '{nameof(IArgsTuple)}' for the specified tuple of args.{Environment.NewLine}\tTuple:{args.FmtStr().GNLI2()}", paramName: hnd.Name); } // return(result.MakeGenericType(typeArguments: args.ArgsTypes.ToArray())); } }
public static NameValueCollection GetQueryParameters(this ArgumentUtilitiesHandle <Uri> uri) => HttpUtility.ParseQueryString(query: HttpUtility.UrlDecode(str: uri.EnsureNotNull().EnsureAbsolute().Value.Query));
TValue P_GetOrAdd(ArgumentUtilitiesHandle <TKey> key, Func <TKey, TValue> valueFactory, Action <TKey, TValue> valueCleanup, bool keyAbsenceRequired, out bool added, bool keyDisposeTolerant = default, TValue keyDisposeSentinel = default) { key.EnsureNotNull(); if (valueFactory is null) { throw new ArgumentNullException(paramName: nameof(valueFactory)); } // valueCleanup = valueCleanup ?? __NopValueCleanup; var isAdded = false; P_ValueHolder newValueHolder = default; P_ValueHolder existingValueHolder = default; Exception caughtException = default; try { itrlck .Update( location: ref _innerTable, transform: (ImmutableDictionary <TKey, P_ValueHolder> locCurrent) => { ImmutableDictionary <TKey, P_ValueHolder> locChanged; if (keyAbsenceRequired) { try { locChanged = locCurrent.Add(key: key.Value, value: newValueHolder ?? (newValueHolder = new P_ValueHolder())); } catch (ArgumentException locException) { throw new ArgumentException( paramName: key.Name, message: $"Specified key is already exists in this table.{Environment.NewLine}\tKey:{key.Value.FmtStr().GNLI2()}", innerException: locException); } } else { locChanged = locCurrent; var locValueHolder = ImmutableInterlocked.GetOrAdd(location: ref locChanged, key: key.Value, valueFactory: locKey => newValueHolder ?? (newValueHolder = new P_ValueHolder())); if (ReferenceEquals(locCurrent, locChanged)) { // Словарь не был изменён (а значит, в словаре уже присутствовало значение для указанного ключа). // existingValueHolder = locValueHolder; } } if (!ReferenceEquals(locCurrent, locChanged) && newValueHolder.ValueCleanup is null) { newValueHolder.Value = valueFactory(arg: key.Value); newValueHolder.ValueCleanup = valueCleanup; if (keyDisposeTolerant) { if (key.Value.IsDisposeRequested) { return(locCurrent); } else { try { key.Value.AfterDisposed += (locSender, locEventArgs) => P_EH_Key_AfterDisposed(sender: locSender, eventArgs: locEventArgs, valueHolder: newValueHolder); } catch (ObjectDisposedException) { return(locCurrent); } } } else { key.Value.AfterDisposed += (locSender, locEventArgs) => P_EH_Key_AfterDisposed(sender: locSender, eventArgs: locEventArgs, valueHolder: newValueHolder); } } return(locChanged); }, isUpdated: out isAdded); if (isAdded) { added = true; return(newValueHolder.Value); } else if (keyDisposeTolerant) { added = false; return(keyDisposeSentinel); } else { added = false; return(existingValueHolder.Value); } } catch (Exception exception) { caughtException = exception; throw; } finally { if (!(isAdded || newValueHolder is null)) { try { itrlck.SetNull(location: ref newValueHolder.ValueCleanup)?.Invoke(arg1: key.Value, arg2: newValueHolder.Value); } catch (Exception exception) { if (caughtException is null) { throw; } else { throw new AggregateException(caughtException, exception); } } } } }
// TODO: Put strings into the resources. // /// <summary> /// Выполняет парсинг параметров, заданных в виде массива строк. /// <para>Каждый элемент массива <paramref name="parameters"/> представляет пару параметр-значение.</para> /// <para>Если элемент массива является <see langword="null"/>, пустой строкой или строкой, содержащей только пробельные символы, то этот элемент пропускается.</para> /// <para>Ожидаемый формат параметра (элемента массива <paramref name="parameters"/>): <имя параметра><разделитель имени параметра и значения (<paramref name="parameterNameDelimiter"/>)><значение параметра>. Значение параметра может быть пустой строкой.</para> /// <para>В качестве компаратора ключей словаря, где ключ — имя параметра, используется <see cref="StringComparer.OrdinalIgnoreCase"/>.</para> /// </summary> /// <param name="parameters"> /// Массив строк, каждый элемент которого представляет отдельную пару параметр-значение. /// <para>Не может быть null.</para> /// </param> /// <param name="parameterNameDelimiter"> /// Символ-разделитель имени параметра и его значения. /// <para>Не может быть пробельным символом (см. <seealso cref="char.IsWhiteSpace(char)"/>).</para> /// </param> /// <returns>Словарь <see cref="IDictionary{TKey, TValue}"/>.</returns> public static IDictionary <string, string> ParseParametersDictionary(ArgumentUtilitiesHandle <string[]> parameters, ArgumentUtilitiesHandle <char> parameterNameDelimiter) { parameters.EnsureNotNull(); if (char.IsWhiteSpace(parameterNameDelimiter.Value)) { throw new ArgumentOutOfRangeException(paramName: parameterNameDelimiter.Name, message: "Значение не может быть пробельным символом."); } // Func <string, char, int, string, string[]> parseArgument = (locParametersArrayArgName, locParameterNameDelimiter, locParameterPosition, locParameterText) => { if (string.IsNullOrWhiteSpace(locParameterText)) { return(null); } else { var locNamePart = new List <char>(); var locValuePart = new List <char>(); var locCurrentPart = locNamePart; var locIsParameterNameDelimiterOccurred = false; for (var i = 0; i < locParameterText.Length; i++) { var locCurrentChar = locParameterText[i]; if (locCurrentChar == locParameterNameDelimiter) { // Символ-разделитель имени и значения параметра. // if (ReferenceEquals(locCurrentPart, locNamePart)) { locIsParameterNameDelimiterOccurred = true; // Удаление конечных "пробелов" в имени. // for (var y = locNamePart.Count - 1; y > -1; y--) { if (char.IsWhiteSpace(locNamePart[y])) { locNamePart.RemoveAt(y); } else { break; } } if (locNamePart.Count < 1) { throw new ArgumentException( message: $"Параметр в позиции '{locParameterPosition.ToString("d")}' имеет недопустимый формат.{Environment.NewLine}\tПараметр:{locParameterText.FmtStr().GNLI2()}", paramName: locParametersArrayArgName); } else { locCurrentPart = locValuePart; } } else { locCurrentPart.Add(locCurrentChar); } } else if (ReferenceEquals(locCurrentPart, locNamePart)) { if (locCurrentPart.Count > 0 || !char.IsWhiteSpace(locCurrentChar)) { locCurrentPart.Add(locCurrentChar); } } else { locCurrentPart.Add(locCurrentChar); } } // if (!locIsParameterNameDelimiterOccurred || locNamePart.Count < 1) { throw new ArgumentException( message: $"Параметр в позиции '{locParameterPosition.ToString("d")}' имеет недопустимый формат.{Environment.NewLine}\tПараметр:{locParameterText.FmtStr().GNLI2()}", paramName: locParametersArrayArgName); } return (new string[] { new string(locNamePart.ToArray()), locValuePart.Count < 1 ? null : new string(locValuePart.ToArray()) }); } }; // var result = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); string[] parameterNameAndValue; for (var i = 0; i < parameters.Value.Length; i++) { parameterNameAndValue = parseArgument( parameters.Name, parameterNameDelimiter.Value, i, parameters.Value[i]); if (parameterNameAndValue == null) { continue; } else if (result.ContainsKey(parameterNameAndValue[0])) { throw new ArgumentException( message: $"Параметр '{parameters.Value[ i ]}' (в позиции {i.ToString("d")}) указан по меньшей мере дважды. Каждый аргумент должен указываться единажды.", paramName: parameters.Name); } result.Add(parameterNameAndValue[0], parameterNameAndValue[1]); } return(result); }