/// <summary> /// Parses a continuous hex stream from a string. /// </summary> /// <param name="s">A string containing continuous hex values without delimiters.</param> /// <returns>A byte array containing the hex values as bytes.</returns> /// <exception cref="ArgumentNullException"><paramref name="s"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"><paramref name="s"/> does not consist of event amount of hex digits, or parsing failed.</exception> public static byte[] ParseHexBytes(this string s) { if (s == null) { Throw.ArgumentNullException(Argument.s); } if (s.Length == 0) { return(Reflector.EmptyArray <byte>()); } if ((s.Length & 1) != 0) { Throw.ArgumentException(Argument.s, Res.StringExtensionsSourceLengthNotEven); } byte[] result = new byte[s.Length >> 1]; for (int i = 0; i < result.Length; i++) { if (!Parser.TryParseHexByte(s, i << 1, out result[i])) { Throw.ArgumentException(Argument.s, Res.StringExtensionsCannotParseAsType(s.Substring(i << 1, 2), Reflector.ByteType)); } } return(result); }
/// <summary> /// Parses separated decimal bytes from a string. /// </summary> /// <param name="s">A string containing delimited decimal integer numbers.</param> /// <param name="separator">A separator delimiting the values.</param> /// <returns>A byte array containing the decimal values as bytes.</returns> /// <exception cref="ArgumentNullException"><paramref name="s"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"><paramref name="separator"/> is <see langword="null"/> or empty.</exception> /// <exception cref="FormatException"><paramref name="s"/> is not of the correct format.</exception> /// <exception cref="OverflowException">A value in <paramref name="s"/> does not fit in the range of a <see cref="byte">byte</see> value.</exception> public static byte[] ParseDecimalBytes(this string s, string separator) { if (s == null) { Throw.ArgumentNullException(Argument.s); } if (String.IsNullOrEmpty(separator)) { Throw.ArgumentException(Argument.separator, Res.StringExtensionsSeparatorNullOrEmpty); } List <StringSegmentInternal> values = new StringSegmentInternal(s).Split(separator); int len = values.Count; byte[] result = new byte[len]; for (int i = 0; i < len; i++) { StringSegmentInternal segment = values[i]; segment.Trim(); if (!segment.TryParseIntQuick(false, Byte.MaxValue, out ulong value)) { Throw.ArgumentException(Argument.s, Res.StringExtensionsCannotParseAsType(segment.ToString(), Reflector.ByteType)); } result[i] = (byte)value; } return(result); }
/// <summary> /// Parses delimited hex values from a string into an array of bytes. /// </summary> /// <param name="s">A string containing delimited hex values.</param> /// <param name="separator">A separator delimiting the hex values. If <see langword="null"/>, then <paramref name="s"/> is parsed as a continuous hex stream.</param> /// <returns>A byte array containing the hex values as bytes.</returns> /// <exception cref="ArgumentNullException"><paramref name="s"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"><paramref name="separator"/> is <see langword="null"/> or empty, and <paramref name="s"/> does not consist of event number of hex digits, /// or parsing failed.</exception> public static byte[] ParseHexBytes(this string s, string separator) { if (s == null) { Throw.ArgumentNullException(Argument.s); } if (string.IsNullOrEmpty(separator)) { return(ParseHexBytes(s)); } List <StringSegmentInternal> values = new StringSegmentInternal(s).Split(separator); int len = values.Count; byte[] result = new byte[len]; for (int i = 0; i < len; i++) { StringSegmentInternal segment = values[i]; segment.Trim(); if (!Parser.TryParseHexByte(segment, out result[i])) { Throw.ArgumentException(Argument.s, Res.StringExtensionsCannotParseAsType(segment.ToString(), Reflector.ByteType)); } } return(result); }
/// <summary> /// Inserts a song from a specified index to a other index in the playlist and moves all songs in between these indexes one index back. /// </summary> /// <param name="fromIndex">The index of the song to move.</param> /// <param name="toIndex">To index to insert the song.</param> public void InsertMove(int fromIndex, int toIndex) { if (fromIndex < 0) { Throw.ArgumentOutOfRangeException(() => fromIndex, 0); } if (toIndex < 0) { Throw.ArgumentOutOfRangeException(() => 0); } if (toIndex >= fromIndex) { Throw.ArgumentException( String.Format("{0} has to be small than {1}", Reflector.GetMemberName(() => toIndex), Reflector.GetMemberName(() => fromIndex)), () => toIndex); } Song from = this[fromIndex]; for (int i = fromIndex; i > toIndex; i--) { this.playlist[i] = this[i - 1]; } this.playlist[toIndex] = from; }
public static object DeserializeValueType(Type type, byte[] data) { if (type == null) { Throw.ArgumentNullException(Argument.type); } if (!type.IsValueType) { Throw.ArgumentException(Argument.type, Res.BinarySerializationValueTypeExpected); } if (data == null) { Throw.ArgumentNullException(Argument.data); } if (data.Length < Marshal.SizeOf(type)) { Throw.ArgumentException(Argument.data, Res.BinarySerializationDataLengthTooSmall); } GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); try { return(Marshal.PtrToStructure(handle.AddrOfPinnedObject(), type)); } finally { handle.Free(); } }
/// <summary> /// Converts the byte array to string of decimal values. /// </summary> /// <param name="bytes">The byte array to convert.</param> /// <param name="separator">The separator to use between the decimal numbers. This parameter is optional. /// <br/>Default value: <c>", "</c> (comma and space)</param> /// <returns>The string representation, in decimal, of the contents of <paramref name="bytes"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="bytes"/> or <paramref name="separator"/> is <see langword="null"/></exception> /// <exception cref="ArgumentException"><paramref name="separator"/> is empty or contains decimal digits</exception> public static string ToDecimalValuesString(this byte[] bytes, string separator = ", ") { if (bytes == null) { Throw.ArgumentNullException(Argument.bytes); } if (separator == null) { Throw.ArgumentNullException(Argument.separator); } if (separator.Length == 0 || separator.Any(c => c >= '0' && c <= '9')) { Throw.ArgumentException(Argument.separator, Res.ByteArrayExtensionsSeparatorInvalidDec); } StringBuilder result = new StringBuilder(bytes.Length * (3 + separator.Length)); for (int i = 0; i < bytes.Length; i++) { result.Append(bytes[i].ToString(CultureInfo.InvariantCulture)); if (i < bytes.Length - 1) { result.Append(separator); } } return(result.ToString()); }
/// <summary> /// Copies the <paramref name="source"/> <see cref="Stream"/> into the <paramref name="destination"/> one. /// Copy begins on the current position of source stream. None of the streams are closed or sought after /// the end of the copy progress. /// </summary> /// <param name="source">Source stream.</param> /// <param name="destination">Destination stream.</param> /// <param name="bufferSize">Size of the buffer used for copying.</param> public static void CopyTo(this Stream source, Stream destination, int bufferSize) { if (source == null) { Throw.ArgumentNullException(Argument.source); } if (destination == null) { Throw.ArgumentNullException(Argument.destination); } if (bufferSize <= 0) { Throw.ArgumentOutOfRangeException(Argument.bufferSize); } if (!source.CanRead) { Throw.ArgumentException(Argument.source, Res.StreamExtensionsStreamCannotRead); } if (!destination.CanWrite) { Throw.ArgumentException(Argument.destination, Res.StreamExtensionsStreamCannotWrite); } byte[] buffer = new byte[bufferSize]; int read; while ((read = source.Read(buffer, 0, buffer.Length)) > 0) { destination.Write(buffer, 0, read); } }
/// <summary> /// Gets whether <paramref name="item"/> is among the results of <paramref name="set"/>. /// </summary> /// <param name="item">The item to search for in the results of <paramref name="set"/>.</param> /// <param name="set">The set of delegates, whose results are checked whether they are equal to the specified <paramref name="item"/>.</param> /// <typeparam name="T">The type of <paramref name="item"/> and the <paramref name="set"/> elements.</typeparam> /// <returns><see langword="true"/> if <paramref name="item"/> is among the results of <paramref name="set"/>; otherwise, <see langword="false"/>.</returns> /// <remarks> /// <para>This method works similarly to the <c>in</c> operator in SQL and Pascal.</para> /// <para>This overload uses generic <see cref="IEqualityComparer{T}"/> implementations to compare the items for the best performance. /// The elements of <paramref name="set"/> are evaluated only when they are actually compared so if a result is found the rest of the elements will not be evaluated. /// <note>If elements of <paramref name="set"/> are constants or simple expressions consider to use the <see cref="In{T}(T,T[])"/> overload to eliminate the overhead of delegate invokes.</note></para> /// </remarks> public static bool In <T>(this T item, params Func <T>[] set) { int length; if (set == null || (length = set.Length) == 0) { return(false); } var comparer = ComparerHelper <T> .EqualityComparer; for (int i = 0; i < length; i++) { Func <T> func = set[i]; if (func == null) { Throw.ArgumentException(Argument.set, Res.ArgumentContainsNull); } if (comparer.Equals(item, func.Invoke())) { return(true); } } return(false); }
/// <summary> /// Converts the byte array to string of hexadecimal values. /// </summary> /// <param name="bytes">The byte array to convert.</param> /// <param name="separator">The separator to use between the hex numbers. If <see langword="null"/> or empty, the hex stream will be continuous. This parameter is optional. /// <br/>Default value: <see langword="null"/>.</param> /// <returns>The string representation, in hex, of the contents of <paramref name="bytes"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="bytes"/> is <see langword="null"/></exception> /// <exception cref="ArgumentException"><paramref name="separator"/> contains hex digits</exception> public static string ToHexValuesString(this byte[] bytes, string separator = null) { if (bytes == null) { Throw.ArgumentNullException(Argument.bytes); } bool useSeparator = !String.IsNullOrEmpty(separator); if (useSeparator && separator.Any(c => c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f')) { Throw.ArgumentException(Argument.separator, Res.ByteArrayExtensionsSeparatorInvalidHex); } StringBuilder result = new StringBuilder(bytes.Length * (2 + (separator ?? String.Empty).Length)); for (int i = 0; i < bytes.Length; i++) { result.Append(bytes[i].ToString("X2", CultureInfo.InvariantCulture)); if (useSeparator && i < bytes.Length - 1) { result.Append(separator); } } return(result.ToString()); }
/// <summary> /// Copies the elements of the <see cref="T:System.Collections.ICollection" /> to an <see cref="T:System.Array" />, starting at a particular <see cref="T:System.Array" /> index. /// </summary> /// <param name="array">The one-dimensional <see cref="T:System.Array" /> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection" />. The <see cref="T:System.Array" /> must have zero-based indexing.</param> /// <param name="index">The zero-based index in <paramref name="array" /> at which copying begins.</param> public void CopyTo(Array array, int index) { if (array == null) { Throw.ArgumentNullException(nameof(array)); } if (index < 0) { Throw.ArgumentOutOfRangeException(nameof(index), index, Message.Common.NonNegativeArrayIndex); } if (index > array.Length) { Throw.ArgumentOutOfRangeException(nameof(index), index, Message.Common.ArrayIndexCannotGreaterThanArraySize); } if (Count > array.Length - index) { Throw.ArgumentException(Message.Common.ArraySizeLess); } if (_head < _tail) { Array.Copy(_array, 0, array, index, Count); return; } Array.Copy(_array, _head, array, 0, _array.Length - _head); Array.Copy(_array, 0, array, _array.Length - _head, _tail); }
/// <summary> /// Gets whether the specified <see cref="string"/> <paramref name="s"/> contains any of the strings in the specified <paramref name="set"/> set using a specific <paramref name="comparison"/>. /// </summary> /// <param name="comparison">The <see cref="StringComparison"/> to use.</param> /// <param name="s">A <see cref="string"/> instance that is to be compared to each element of the <paramref name="set"/>.</param> /// <param name="set">A string array</param> /// <returns><see langword="true"/> if string <paramref name="s"/> contains any of the elements of <paramref name="set"/>; otherwise, <see langword="false"/>.</returns> /// <exception cref="ArgumentNullException"><paramref name="s"/> is <see langword="null"/> /// <br/>-or- /// <br/><paramref name="set"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="comparison"/> is not a defined <see cref="StringComparison"/> value.</exception> /// <exception cref="ArgumentException"><paramref name="set"/>contains a <see langword="null"/> element.</exception> public static bool ContainsAny(this string s, StringComparison comparison, params string[] set) { if (!Enum <StringComparison> .IsDefined(comparison)) { Throw.EnumArgumentOutOfRange(Argument.comparison, comparison); } if (s == null) { Throw.ArgumentNullException(Argument.s); } if (set == null) { Throw.ArgumentNullException(Argument.set); } foreach (var str in set) { if (str == null) { Throw.ArgumentException(Argument.set, Res.ArgumentContainsNull); } if (s.IndexOf(str, comparison) >= 0) { return(true); } } return(false); }
/// <summary> /// Parses a continuous hex stream from a string. /// </summary> /// <param name="s">A string containing continuous hex values without delimiters.</param> /// <returns>A byte array containing the hex values as bytes.</returns> /// <exception cref="ArgumentNullException"><paramref name="s"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"><paramref name="s"/> does not consist of event amount of hex digits.</exception> /// <exception cref="FormatException"><paramref name="s"/> is not of the correct format.</exception> /// <exception cref="OverflowException">A value in <paramref name="s"/> does not fit in the range of a <see cref="byte">byte</see> value.</exception> public static byte[] ParseHexBytes(this string s) { if (s == null) { Throw.ArgumentNullException(Argument.s); } if (s.Length == 0) { return(Reflector.EmptyArray <byte>()); } if (s.Length % 2 != 0) { Throw.ArgumentException(Argument.s, Res.StringExtensionsSourceLengthNotEven); } byte[] result = new byte[s.Length >> 1]; for (int i = 0; i < (s.Length >> 1); i++) { result[i] = Byte.Parse(s.Substring(i << 1, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture); } return(result); }
/// <summary> /// Inserts a song from a specified index to a other index in the playlist and moves all songs in between these indexes /// one index back. /// </summary> /// <param name="fromIndex">The index of the song to move.</param> /// <param name="toIndex">To index to insert the song.</param> internal void InsertMove(int fromIndex, int toIndex) { if (fromIndex < 0) { Throw.ArgumentOutOfRangeException(() => fromIndex, 0); } if (toIndex < 0) { Throw.ArgumentOutOfRangeException(() => toIndex, 0); } if (toIndex >= fromIndex) { Throw.ArgumentException( String.Format("{0} has to be smaller than {1}", Reflector.GetMemberName(() => toIndex), Reflector.GetMemberName(() => fromIndex)), () => toIndex); } PlaylistEntry from = this[fromIndex]; for (int i = fromIndex; i > toIndex; i--) { _playlist[i].Index = i - 1; _playlist[i] = this[i - 1]; } from.Index = toIndex; _playlist[toIndex] = from; }
public void CopyTo(T[] array, int arrayIndex) { if (array == null) { Throw.ArgumentNullException(nameof(array)); } if (arrayIndex < 0) { Throw.ArgumentOutOfRangeException(nameof(arrayIndex), Message.Common.NonNegativeArrayIndex); } if (arrayIndex > array.Length) { Throw.ArgumentOutOfRangeException(nameof(arrayIndex), Message.Common.ArrayIndexCannotGreaterThanArraySize); } if (Count > array.Length - arrayIndex) { Throw.ArgumentException(Message.Common.ArraySizeLess); } if (IsEmpty) { return; } var current = Head; while (current != null) { array[arrayIndex++] = current.Item; current = current.Next; } }
internal static void CheckDestinationLength(this ISignAlgorithm a, int len) { if (len < a.SignatureByteLength) { Throw.ArgumentException($"Signature algorithm '{a.AlgorithmId}' requires {a.SignatureByteLength} destination bytes. Provided buffer has only {len} bytes.", "destination"); } }
public static byte[] ToArray(this Stream s) { if (s == null) { Throw.ArgumentNullException(Argument.s); } if (!s.CanRead) { Throw.ArgumentException(Argument.s, Res.StreamExtensionsStreamCannotRead); } if (s is MemoryStream ms) { return(ms.ToArray()); } if (!s.CanSeek) { using (ms = new MemoryStream()) { CopyTo(s, ms); return(ms.ToArray()); } } long pos = s.Position; try { if (pos != 0L) { s.Seek(0, SeekOrigin.Begin); } byte[] result = new byte[s.Length]; int len = s.Read(result, 0, result.Length); // we could read the whole stream in one step if (len == s.Length) { return(result); } // we use the buffer with the first fragment and continue reading using (ms = new MemoryStream(result, 0, len, true, true) { Position = len }) { CopyTo(s, ms); // if the stream still reports the same length we return its internal buffer to prevent duplicating the array in memory; otherwise, returning a new array return(ms.Length == s.Length ? ms.GetBuffer() : ms.ToArray()); } } finally { s.Seek(pos, SeekOrigin.Begin); } }
private protected static object CreateCollectionByInitializerCollection(ConstructorInfo collectionCtor, IEnumerable initializerCollection, Dictionary <MemberInfo, object> members) { initializerCollection = initializerCollection.AdjustInitializerCollection(collectionCtor); object result = CreateInstanceAccessor.GetAccessor(collectionCtor).CreateInstance(initializerCollection); // restoring fields and properties of the final collection foreach (KeyValuePair <MemberInfo, object> member in members) { var property = member.Key as PropertyInfo; var field = property != null ? null : member.Key as FieldInfo; // read-only property if (property?.CanWrite == false) { object existingValue = property.Get(result); if (property.PropertyType.IsValueType) { if (Equals(existingValue, member.Value)) { continue; } Throw.SerializationException(Res.XmlSerializationPropertyHasNoSetter(property.Name, collectionCtor.DeclaringType)); } if (existingValue == null && member.Value == null) { continue; } if (member.Value == null) { Throw.ReflectionException(Res.XmlSerializationPropertyHasNoSetterCantSetNull(property.Name, collectionCtor.DeclaringType)); } if (existingValue == null) { Throw.ReflectionException(Res.XmlSerializationPropertyHasNoSetterGetsNull(property.Name, collectionCtor.DeclaringType)); } if (existingValue.GetType() != member.Value.GetType()) { Throw.ArgumentException(Res.XmlSerializationPropertyTypeMismatch(collectionCtor.DeclaringType, property.Name, member.Value.GetType(), existingValue.GetType())); } CopyContent(member.Value, existingValue); continue; } // read-write property if (property != null) { property.Set(result, member.Value); continue; } // field field.Set(result, member.Value); } return(result); }
/// <summary> /// Converts the string representation of the name or numeric value of one or more enumerated values to an equivalent enumerated object. /// </summary> /// <param name="value">The string representation of the enumerated value or values to parse.</param> /// <param name="ignoreCase">If <see langword="true"/>, ignores case; otherwise, regards case.</param> /// <returns>The parsed <see langword="enum"/> value.</returns> /// <exception cref="ArgumentException"><paramref name="value"/> cannot be parsed as <typeparamref name="TEnum"/>.</exception> public static TEnum Parse(ReadOnlySpan <char> value, bool ignoreCase) { if (!TryParse(value, default, ignoreCase, out TEnum result)) { Throw.ArgumentException(Argument.value, Res.EnumValueCannotBeParsedAsEnum(value.ToString(), typeof(TEnum))); } return(result); }
/// <summary> /// Converts the string representation of the name or numeric value of one or more enumerated values to an equivalent enumerated object. /// </summary> /// <param name="value">The string representation of the enumerated value or values to parse.</param> /// <param name="separator">In case of more values specified the separator among the values. If <see cref="StringSegment.Null"/> or <see cref="StringSegment.Empty"/>, then comma (<c>,</c>) separator is used. This parameter is optional. /// <br/>Default value: <see cref="StringSegment.Null"/>.</param> /// <param name="ignoreCase">If <see langword="true"/>, ignores case; otherwise, regards case. This parameter is optional. /// <br/>Default value: <see langword="false"/>.</param> /// <returns>The parsed <see langword="enum"/> value.</returns> /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see cref="StringSegment.Null"/>.</exception> /// <exception cref="ArgumentException"><paramref name="value"/> cannot be parsed as <typeparamref name="TEnum"/>.</exception> public static TEnum Parse(StringSegment value, StringSegment separator = default, bool ignoreCase = false) { if (!TryParse(value, separator, ignoreCase, out TEnum result)) { Throw.ArgumentException(Argument.value, Res.EnumValueCannotBeParsedAsEnum(value.ToString(), typeof(TEnum))); } return(result); }
/// <summary> /// Parses an object from a <see cref="string"/> value. Firstly, it tries to parse the type natively. /// If <paramref name="type"/> cannot be parsed natively but the type has a <see cref="TypeConverter"/> or a registered conversion that can convert from string, /// then the type converter or conversion will be used. /// <br/>See the <strong>Remarks</strong> section of the <see cref="Parse{T}"/> overload for details. /// </summary> /// <returns>An object of <paramref name="type"/>, which is the result of the parsing.</returns> /// <param name="s">The string value to parse. If <see langword="null"/> and <paramref name="type"/> is a reference or nullable type, then returns <see langword="null"/>.</param> /// <param name="type">The desired type of the return value.</param> /// <param name="culture">The culture to use for the parsing. If <see langword="null"/>, then the <see cref="CultureInfo.InvariantCulture"/> will be used. This parameter is optional. /// <br/>Default value: <see langword="null"/>.</param> /// <returns>The parsed value.</returns> /// <exception cref="ArgumentNullException"><paramref name="type"/> is <see langword="null"/>, or <paramref name="type"/> is not nullable and <paramref name="s"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Parameter <paramref name="s"/> cannot be parsed as <paramref name="type"/>.</exception> public static object Parse(this string s, Type type, CultureInfo culture = null) { if (!Parser.TryParse(s, type, culture, out object value, out Exception error) || !type.CanAcceptValue(value)) { Throw.ArgumentException(Argument.obj, Res.StringExtensionsCannotParseAsType(s, type), error); } return(value); }
/// <summary> /// Parses an object of type <typeparamref name="T"/> from a <see cref="string">string</see> value. Firstly, it tries to parse the type natively. /// If <typeparamref name="T"/> cannot be parsed natively but the type has a <see cref="TypeConverter"/> or a registered conversion that can convert from string, /// then the type converter or conversion will be used. /// <br/>See the <strong>Remarks</strong> section for details. /// </summary> /// <typeparam name="T">The desired type of the return value.</typeparam> /// <param name="s">The string value to parse. If <see langword="null"/> and <typeparamref name="T"/> is a reference or nullable type, then returns <see langword="null"/>.</param> /// <param name="culture">The culture to use for the parsing. If <see langword="null"/>, then the <see cref="CultureInfo.InvariantCulture"/> will be used. This parameter is optional. /// <br/>Default value: <see langword="null"/>.</param> /// <returns>An object of <typeparamref name="T"/>, which is the result of the parsing.</returns> /// <remarks> /// <para>New conversions can be registered by the <see cref="O:KGySoft.CoreLibraries.TypeExtensions.RegisterConversion">RegisterConversion</see> extension methods.</para> /// <para>A <see cref="TypeConverter"/> can be registered by the <see cref="TypeExtensions.RegisterTypeConverter{TConverter}">RegisterTypeConverter</see> extension method.</para> /// <para>Natively parsed types: /// <list type="bullet"> /// <item><description><see cref="System.Enum"/> based types</description></item> /// <item><description><see cref="string"/></description></item> /// <item><description><see cref="char"/></description></item> /// <item><description><see cref="byte"/></description></item> /// <item><description><see cref="sbyte"/></description></item> /// <item><description><see cref="short"/></description></item> /// <item><description><see cref="ushort"/></description></item> /// <item><description><see cref="int"/></description></item> /// <item><description><see cref="uint"/></description></item> /// <item><description><see cref="long"/></description></item> /// <item><description><see cref="ulong"/></description></item> /// <item><description><see cref="float"/></description></item> /// <item><description><see cref="double"/></description></item> /// <item><description><see cref="decimal"/></description></item> /// <item><description><see cref="bool"/></description></item> /// <item><description><see cref="IntPtr"/></description></item> /// <item><description><see cref="UIntPtr"/></description></item> /// <item><description><see cref="Type"/></description></item> /// <item><description><see cref="DateTime"/></description></item> /// <item><description><see cref="DateTimeOffset"/></description></item> /// <item><description><see cref="TimeSpan"/></description></item> /// <item><description><see cref="Nullable{T}"/> of types above: <see langword="null"/> or empty value returns <see langword="null"/>; otherwise, <paramref name="s"/> is parsed as the underlying type</description></item> /// </list> /// </para> /// </remarks> /// <exception cref="ArgumentNullException"><typeparamref name="T"/> is not nullable and <paramref name="s"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Parameter <paramref name="s"/> cannot be parsed as <typeparamref name="T"/>.</exception> public static T Parse <T>(this string s, CultureInfo culture = null) { if (!Parser.TryParse(s, culture, out T value, out Exception error)) { Throw.ArgumentException(Argument.obj, Res.StringExtensionsCannotParseAsType(s, typeof(T)), error); } return(value); }
/// <summary> /// Converts the string representation of the name or numeric value of one or more enumerated values to an equivalent enumerated object. /// </summary> /// <param name="value">The <see cref="string">string</see> representation of the enumerated value or values to parse.</param> /// <param name="ignoreCase">If <see langword="true"/>, ignores case; otherwise, regards case.</param> /// <returns>The parsed <see langword="enum"/> value.</returns> /// <exception cref="ArgumentNullException"><paramref name="value"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException"><paramref name="value"/> cannot be parsed as <typeparamref name="TEnum"/>.</exception> public static TEnum Parse(string value, bool ignoreCase) { if (!TryParse(value, EnumExtensions.DefaultParseSeparator, ignoreCase, out TEnum result)) { Throw.ArgumentException(Argument.value, Res.EnumValueCannotBeParsedAsEnum(value, typeof(TEnum))); } return(result); }
/// <summary> /// Converts an <see cref="object"/> specified in the <paramref name="obj"/> parameter to the desired <paramref name="targetType"/>. /// <br/>See the <strong>Examples</strong> section of the generic <see cref="Convert{TTarget}"/> overload for an example. /// </summary> /// <param name="targetType">The desired type of the return value.</param> /// <param name="obj">The object to convert.</param> /// <param name="culture">The culture to use for the conversion. If <see langword="null"/>, then the <see cref="CultureInfo.InvariantCulture"/> will be used. This parameter is optional. /// <br/>Default value: <see langword="null"/>.</param> /// <returns>An object of <paramref name="targetType"/>, which is the result of the conversion.</returns> /// <exception cref="ArgumentException"><paramref name="obj"/> cannot be converted to <paramref name="targetType"/>.</exception> /// <remarks> /// <para>New conversions can be registered by the <see cref="O:KGySoft.CoreLibraries.TypeExtensions.RegisterConversion">RegisterConversion</see> <see cref="Type"/> extension methods.</para> /// <note type="tip">The registered conversions are tried to be used for intermediate conversion steps if possible. For example, if a conversion is registered from <see cref="long"/> to <see cref="IntPtr"/>, /// then conversions from other convertible types become automatically available using the <see cref="long"/> type as an intermediate conversion step.</note> /// <para><paramref name="targetType"/> can be even a collection type if <paramref name="obj"/> is also an <see cref="IEnumerable"/> implementation. /// The target collection type must have either a default constructor or a constructor that can accept a list, array or dictionary as an initializer collection.</para> /// </remarks> public static object Convert(this object obj, Type targetType, CultureInfo culture = null) { if (!ObjectConverter.TryConvert(obj, targetType, culture, out object result, out Exception error) || !targetType.CanAcceptValue(result)) { Throw.ArgumentException(Argument.obj, Res.ObjectExtensionsCannotConvertToType(targetType), error); } return(result); }
/// <summary> /// Converts an <see cref="object"/> specified in the <paramref name="obj"/> parameter to the desired <typeparamref name="TTarget"/>. /// </summary> /// <typeparam name="TTarget">The desired type of the return value.</typeparam> /// <param name="obj">The object to convert.</param> /// <param name="culture">The culture to use for the conversion. If <see langword="null"/>, then the <see cref="CultureInfo.InvariantCulture"/> will be used. This parameter is optional. /// <br/>Default value: <see langword="null"/>.</param> /// <returns>An object of <typeparamref name="TTarget"/>, which is the result of the conversion.</returns> /// <exception cref="ArgumentException"><paramref name="obj"/> cannot be converted to <typeparamref name="TTarget"/>.</exception> /// <remarks> /// <para>The method firstly tries to use registered direct conversions between source and target types, then attempts to perform the conversion via <see cref="IConvertible"/> types and registered <see cref="TypeConverter"/>s. /// If these attempts fail, then the registered conversions tried to be used for intermediate steps, if possible.</para> /// <para>New conversions can be registered by the <see cref="O:KGySoft.CoreLibraries.TypeExtensions.RegisterConversion">RegisterConversion</see> <see cref="Type"/> extension methods.</para> /// <para>A <see cref="TypeConverter"/> can be registered by the <see cref="TypeExtensions.RegisterTypeConverter{TConverter}">RegisterTypeConverter</see> <see cref="Type"/> extension method.</para> /// <note type="tip">The registered conversions are tried to be used for intermediate conversion steps if possible. For example, if a conversion is registered from <see cref="long"/> to <see cref="IntPtr"/>, /// then conversions from other convertible types become automatically available using the <see cref="long"/> type as an intermediate conversion step.</note> /// <para><typeparamref name="TTarget"/> can be even a collection type if <paramref name="obj"/> is also an <see cref="IEnumerable"/> implementation. /// The target collection type must have either a default constructor or a constructor that can accept a list, array or dictionary as an initializer collection.</para> /// </remarks> /// <example> /// <note type="tip">Try also <a href="https://dotnetfiddle.net/rzg8If" target="_blank">online</a>.</note> /// <code lang="C#"><![CDATA[ /// using System; /// using System.Collections; /// using System.Collections.Generic; /// using System.Collections.ObjectModel; /// using System.Linq; /// using KGySoft.CoreLibraries; /// /// public class Example /// { /// public static void Main() /// { /// // between convertible types: like the Convert class but supports also enums in both ways /// ConvertTo<int>("123"); // culture can be specified, default is InvariantCulture /// ConvertTo<float>(ConsoleColor.Blue); /// ConvertTo<ConsoleColor>(13); // this would fail by Convert.ChangeType /// /// // TypeConverters are used if possible: /// ConvertTo<Guid>("AADC78003DAB4906826EFD8B2D5CF33D"); /// /// // New conversions can be registered: /// ConvertTo<IntPtr>(42L); // fail /// typeof(long).RegisterConversion(typeof(IntPtr), (obj, type, culture) => new IntPtr((long)obj)); /// ConvertTo<IntPtr>(42L); // success /// /// // Registered conversions can be used as intermediate steps: /// ConvertTo<IntPtr>('x'); // char => long => IntPtr /// /// // Collection conversion is also supported: /// ConvertTo<bool[]>(new List<int> { 1, 0, 0, 1 }); /// ConvertTo<List<int>>("Blah"); // works because string is an IEnumerable<char> /// ConvertTo<string>(new[] { 'h', 'e', 'l', 'l', 'o' }); // because string has a char[] constructor /// ConvertTo<ReadOnlyCollection<string>>(new[] { 1.0m, 2, -1 }); // via the IList<T> constructor /// /// // even between non-generic collections: /// ConvertTo<ArrayList>(new HashSet<int> { 1, 2, 3 }); /// ConvertTo<Dictionary<ConsoleColor, string>>(new Hashtable { { 1, "One" }, { "Black", 'x' } }); /// } /// /// private static void ConvertTo<T>(object source) /// { /// Console.Write($"{source.GetType().GetName(TypeNameKind.ShortName)} => {typeof(T).GetName(TypeNameKind.ShortName)}: {AsString(source)} => "); /// try /// { /// T result = source.Convert<T>(); // a culture can be specified here for string conversions /// Console.WriteLine(AsString(result)); /// } /// catch (Exception e) /// { /// Console.WriteLine(e.Message.Replace(Environment.NewLine, " ")); /// } /// } /// /// private static string AsString(object obj) /// { /// if (obj == null) /// return "<null>"; /// /// // KeyValuePair has a similar ToString to this one /// if (obj is DictionaryEntry de) /// return $"[{de.Key}, {de.Value}]"; /// /// if (!(obj is IEnumerable) || obj is string) /// return obj.ToString(); /// /// return String.Join(", ", ((IEnumerable)obj).Cast<object>().Select(AsString)); /// } /// } /// /// // This example produces the following output: /// // String => Int32: 123 => 123 /// // ConsoleColor => Single: Blue => 9 /// // Int32 => ConsoleColor: 13 => Magenta /// // String => Guid: AADC78003DAB4906826EFD8B2D5CF33D => aadc7800-3dab-4906-826e-fd8b2d5cf33d /// // Int64 => IntPtr: 42 => The specified argument cannot be converted to type System.IntPtr. Parameter name: obj /// // Int64 => IntPtr: 42 => 42 /// // Char => IntPtr: x => 120 /// // List`1 => Boolean[]: 1, 0, 0, 1 => True, False, False, True /// // String => List`1: Blah => 66, 108, 97, 104 /// // Char[] => String: h, e, l, l, o => hello /// // Decimal[] => ReadOnlyCollection`1: 1.0, 2, -1 => 1.0, 2, -1 /// // HashSet`1 => ArrayList: 1, 2, 3 => 1, 2, 3 /// // Hashtable => Dictionary`2: [1, One], [Black, x] => [DarkBlue, One], [Black, x]]]></code> /// </example> public static TTarget Convert <TTarget>(this object obj, CultureInfo culture = null) { if (!ObjectConverter.TryConvert(obj, typeof(TTarget), culture, out object result, out Exception error) || (!(result is TTarget) && !typeof(TTarget).CanAcceptValue(result))) { Throw.ArgumentException(Argument.obj, Res.ObjectExtensionsCannotConvertToType(typeof(TTarget)), error); } return((TTarget)result); }
public T From <T>(byte[] data, Type messageType) { if (data is null || data.Length == 0) { Throw.ArgumentException(nameof(data), "Cannot be null or empty"); } return((T)serializer.Deserialize(messageType, data)); }
public T From <T>(string data, Type messageType) { if (string.IsNullOrWhiteSpace(data)) { Throw.ArgumentException(nameof(data), "Cannot be null, empty or whitespace"); } return(From <T>(Convert.FromBase64String(data), messageType)); }
public T From <T>(string data, Type messageType) { if (string.IsNullOrWhiteSpace(data)) { Throw.ArgumentException(nameof(data), "Cannot be null, empty or whitespace"); } return((T)JsonSerializer.Deserialize(data, messageType, _settings)); }
public T From <T>(byte[] data, Type messageType) { if (data is null || data.Length == 0) { Throw.ArgumentException(nameof(data), "Cannot be null or empty"); } return((T)JSON.Deserialize(Encoding.UTF8.GetString(data), messageType)); }
public T?From <T>(byte[] data, Type messageType) where T : class { if (data is null || data.Length == 0) { Throw.ArgumentException(nameof(data), "Cannot be null or empty"); } return((T?)JsonSerializer.Deserialize(data, messageType, _settings)); }
private protected static void HandleDeserializedMember(object obj, MemberInfo member, object deserializedValue, object existingValue, Dictionary <MemberInfo, object> members) { // 1/a.) Cache for later (obj is an initializer collection) if (members != null) { members[member] = deserializedValue; return; } // 1/b.) Successfully deserialized into the existing instance (or both are null) if (!(deserializedValue is ValueType) && ReferenceEquals(existingValue, deserializedValue)) { return; } // 1.c.) Processing result // Field if (member is FieldInfo field) { field.Set(obj, deserializedValue); return; } var property = (PropertyInfo)member; // Read-only property if (!property.CanWrite) { if (property.PropertyType.IsValueType) { if (Equals(existingValue, deserializedValue)) { return; } Throw.SerializationException(Res.XmlSerializationPropertyHasNoSetter(property.Name, obj.GetType())); } if (existingValue == null) { Throw.ReflectionException(Res.XmlSerializationPropertyHasNoSetterGetsNull(property.Name, obj.GetType())); } if (deserializedValue == null) { Throw.ReflectionException(Res.XmlSerializationPropertyHasNoSetterCantSetNull(property.Name, obj.GetType())); } if (existingValue.GetType() != deserializedValue.GetType()) { Throw.ArgumentException(Res.XmlSerializationPropertyTypeMismatch(obj.GetType(), property.Name, deserializedValue.GetType(), existingValue.GetType())); } CopyContent(deserializedValue, existingValue); return; } // Read-write property property.Set(obj, deserializedValue); }