Skip to content

Instantly share code, notes, and snippets.

@JakubNei
Last active August 23, 2019 08:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JakubNei/d6a253b7ae969d146aaa91691e3af006 to your computer and use it in GitHub Desktop.
Save JakubNei/d6a253b7ae969d146aaa91691e3af006 to your computer and use it in GitHub Desktop.
Collection of useful .NET extensions I've made over the years. I usually carry this to any project I work on.
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
/// <summary>
/// Version 2017-07-08 (yyyy-MM-dd)
/// Collection of useful .NET extensions I've made over the years. I usually carry this to any project I work on.
/// </summary>
public static class NeitriBaseExtensions
{
#region Enum extensions
public static bool HasFlag(this Enum variable, Enum value)
{
if (variable == null)
return false;
if (value == null)
throw new ArgumentNullException("value");
// Not as good as the .NET 4 version of this function, but should be good enough
if (!Enum.IsDefined(variable.GetType(), value))
{
throw new ArgumentException(string.Format(
"Enumeration type mismatch. The flag is of type '{0}', was expecting '{1}'.",
value.GetType(), variable.GetType()));
}
ulong num = Convert.ToUInt64(value);
return ((Convert.ToUInt64(variable) & num) == num);
}
#endregion
#region Action extensions
static public void Raise(this Action handler)
{
if (handler != null) handler();
}
static public void Raise<T1>(this Action<T1> handler, T1 a)
{
if (handler != null) handler(a);
}
static public void Raise<T1, T2>(this Action<T1, T2> handler, T1 a, T2 b)
{
if (handler != null) handler(a, b);
}
static public void Raise<T1, T2, T3>(this Action<T1, T2, T3> handler, T1 a, T2 b, T3 c)
{
if (handler != null) handler(a, b, c);
}
static public void Raise<T1, T2, T3, T4>(this Action<T1, T2, T3, T4> handler, T1 a, T2 b, T3 c, T4 d)
{
if (handler != null) handler(a, b, c, d);
}
#endregion
#region IDictionary<> extensions
/// <summary>
/// Tries to TryGetValue value by key, if not found new value is created with value of defaultValue, new value is NOT added to the Dictionary
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="dictionary"></param>
/// <param name="key"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TValue GetValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue)
{
TValue value;
if (!dictionary.TryGetValue(key, out value))
{
value = defaultValue;
}
return value;
}
/// <summary>
/// Tries to TryGetValue value by key, if not found new value is created, new value is NOT added to the Dictionary.
/// If TValue is class new value is new TValue(), otherwise its default(TValue)
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="dictionary"></param>
/// <param name="key"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TValue GetValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
{
TValue value;
if (!dictionary.TryGetValue(key, out value))
{
value = default(TValue);
}
return value;
}
/// <summary>
/// Tries to TryGetValue value by key, if not found new value is created with value of defaultValue, new value is added to the Dictionary.
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="dictionary"></param>
/// <param name="key"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue)
{
TValue value;
if (!dictionary.TryGetValue(key, out value))
{
value = defaultValue;
dictionary[key] = value;
}
return value;
}
/// <summary>
/// Tries to TryGetValue value by key, if not found new value is created, new value is added to the Dictionary.
/// TValue must have parameterless constructor: new TValue()
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="dictionary"></param>
/// <param name="key"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key) where TValue : new()
{
TValue value;
if (dictionary.TryGetValue(key, out value) == false)
{
value = new TValue();
dictionary[key] = value;
}
return value;
}
/// <summary>
/// Tries to TryGetValue value by key, if not found new value is created with value returned by Func defaultValueFunc, new value is added to the Dictionary
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="dictionary"></param>
/// <param name="key"></param>
/// <param name="defaultValueFunc">Is caled only if it is needed, that is when key is not found</param>
/// <returns></returns>
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> defaultValueFunc)
{
TValue value;
if (!dictionary.TryGetValue(key, out value))
{
value = defaultValueFunc();
dictionary[key] = value;
}
return value;
}
/// <summary>
/// Tries to TryGetValue value by key, if not found new value is created with value returned by Func defaultValueFunc, new value is added to the Dictionary
/// </summary>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TValue"></typeparam>
/// <param name="dictionary"></param>
/// <param name="key"></param>
/// <param name="defaultValueFunc">Is caled only if it is needed, that is when key is not found</param>
/// <returns></returns>
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TValue> defaultValueFunc)
{
TValue value;
if (!dictionary.TryGetValue(key, out value))
{
value = defaultValueFunc(key);
dictionary[key] = value;
}
return value;
}
#endregion
#region List<T> extensions
public static void Resize<T>(this List<T> list, int newCount, T defaultValue)
{
int currentCount = list.Count;
if (newCount < currentCount)
list.RemoveRange(newCount, currentCount - newCount);
else if (newCount > currentCount)
{
if (newCount > list.Capacity)//this bit is purely an optimisation, to avoid multiple automatic capacity changes.
list.Capacity = newCount;
list.AddRange(Enumerable.Repeat(defaultValue, newCount - currentCount));
}
}
public static void Resize<T>(this List<T> list, int newCount)
{
Resize(list, newCount, default(T));
}
#endregion
#region IList<T> extensions
public static T First<T>(this IList<T> list)
{
return list[0];
}
public static T FirstOrDefault<T>(this IList<T> list)
{
if (list.Count > 0)
return list[0];
return default(T);
}
public static T Last<T>(this IList<T> list)
{
return list[list.Count - 1];
}
public static T LastOrDefault<T>(this IList<T> list)
{
if (list.Count > 0)
return list[list.Count - 1];
return default(T);
}
public static int Count<T>(this IList<T> list)
{
return list.Count;
}
public static long LongCount<T>(this IList<T> list)
{
return (long)list.Count;
}
#endregion
#region IList<T> and IList extensions
public static void AddRange(this IList me, IEnumerable enumerable)
{
if (me == null) throw new NullReferenceException("me");
if (enumerable == null) throw new NullReferenceException("enumerable");
foreach (object e in enumerable)
{
me.Add(e);
}
}
public static void AddRange(this IList me, IList other)
{
if (me == null) throw new NullReferenceException("me");
if (other == null) throw new NullReferenceException("other");
foreach (object e in other)
{
me.Add(e);
}
}
public static void AddRange<T>(this IList<T> me, IEnumerable<T> enumerable)
{
if (me == null) throw new NullReferenceException("me");
if (enumerable == null) throw new NullReferenceException("enumerable");
foreach (var e in enumerable)
{
me.Add(e);
}
}
public static void AddRange<T>(this IList<T> me, IList<T> other)
{
if (me == null) throw new NullReferenceException("me");
if (other == null) throw new NullReferenceException("other");
foreach (var e in other)
{
me.Add(e);
}
}
#endregion
#region IEnumerable<T> extensions
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
{
foreach (var item in enumerable)
{
action(item);
}
}
public static void ForEach<TInput, TResult>(this IEnumerable<TInput> enumerable, Func<TInput, TResult> action)
{
foreach (var item in enumerable)
{
action(item);
}
}
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T, int> action)
{
int index = 0;
foreach (var item in enumerable)
{
action(item, index);
}
}
public static T FindClosest<T>(this IEnumerable<T> enumerable, Func<T, float> distanceFunc, float initialClosestDist = float.MaxValue)
{
T closestEnumerable = default(T);
float closestDist = initialClosestDist;
foreach (var e in enumerable)
{
float dist = distanceFunc(e);
if (dist < closestDist)
{
closestDist = dist;
closestEnumerable = e;
}
}
return closestEnumerable;
}
public static IEnumerable<T> Concat<T>(this IEnumerable<IEnumerable<T>> enumerable)
{
IEnumerable<T> result = null;
foreach (var e in enumerable)
{
if (result == null) result = e;
else result = result.Concat(e);
}
return result;
}
public static int GetContentsHashCode<T>(this IEnumerable<T> enumerable)
{
int hashCode = 0;
foreach (var e in enumerable)
hashCode ^= e.GetHashCode();
return hashCode;
}
/// <summary>
/// Ruby style Array.map
/// </summary>
public static IEnumerable<TResult> Map<TInput, TResult>(this IEnumerable<TInput> enumerable, Func<TInput, TResult> selector)
{
return enumerable.Select(selector);
}
/// <summary>
/// Ruby style Array.each
/// </summary>
public static void Each<T>(this IEnumerable<T> enumerable, Action<T> action)
{
enumerable.ForEach(action);
}
/// <summary>
/// Ruby style Array.uniq
/// </summary>
public static IEnumerable<T> Uniq<T>(this IEnumerable<T> enumerable)
{
return enumerable.Distinct();
}
#endregion
#region IEnumerable<char> extensions
public static string Join(this IEnumerable<char> enumerable, char glue)
{
return string.Join(glue.ToString(), enumerable.Select(c => c.ToString()).ToArray());
}
public static string Join(this IEnumerable<char> enumerable, string glue)
{
return string.Join(glue, enumerable.Select(c => c.ToString()).ToArray());
}
#endregion
#region IEnumerable<string> extensions
public static string Join(this IEnumerable<string> enumerable, string glue)
{
return string.Join(glue, enumerable.ToArray());
}
public static string Join(this IEnumerable<string> enumerable, char glue)
{
return string.Join(glue.ToString(), enumerable.ToArray());
}
#endregion
#region T[] extensions
public static T First<T>(this T[] array)
{
return array[0];
}
public static T FirstOrDefault<T>(this T[] array)
{
if (array.Length > 0)
return array[0];
return default(T);
}
public static T Last<T>(this T[] array)
{
return array[array.Length - 1];
}
public static T LastOrDefault<T>(this T[] array)
{
if (array.Length > 0)
return array[array.Length - 1];
return default(T);
}
public static int Count<T>(this T[] array)
{
return array.Length;
}
public static long LongCount<T>(this T[] array)
{
return (long)array.Length;
}
#endregion
#region T[,] extensions
public static IEnumerable<T> ToEnumerable<T>(this T[,] target)
{
foreach (T item in target)
yield return item;
}
#endregion
#region byte[] extensions
// from http://stackoverflow.com/questions/623104/byte-to-hex-string
/// <summary>
/// Returns hex representation of byte array, {1, 2, 4, 8, 16, 32} would return 010204081020.
/// </summary>
/// <param name="bytes"></param>
/// <returns></returns>
public static string ToHexString(this byte[] bytes)
{
char[] c = new char[bytes.Length * 2];
byte b;
for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx)
{
b = ((byte)(bytes[bx] >> 4));
c[cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
b = ((byte)(bytes[bx] & 0x0F));
c[++cx] = (char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
}
return new string(c);
}
// from http://stackoverflow.com/questions/16340/how-do-i-generate-a-hashcode-from-a-byte-array-in-c
public static int ComputeHashCodeSlow(this byte[] data)
{
unchecked
{
const int p = 16777619;
int hash = (int)2166136261;
for (int i = 0; i < data.Length; i++)
hash = (hash ^ data[i]) * p;
hash += hash << 13;
hash ^= hash >> 7;
hash += hash << 3;
hash ^= hash >> 17;
hash += hash << 5;
return hash;
}
}
public static int ComputeHashCodeFast(this byte[] byteArray)
{
// http://stackoverflow.com/questions/16340/how-do-i-generate-a-hashcode-from-a-byte-array-in-c
var str = Convert.ToBase64String(byteArray);
return str.GetHashCode();
}
#endregion
#region float extensions
public static float Abs(this float a)
{
return System.Math.Abs(a);
}
public static float Pow(this float x, float power)
{
return (float)System.Math.Pow(x, power);
}
public static float Max(this float me, float other)
{
if (me > other) return me;
return other;
}
public static float Min(this float me, float other)
{
if (me < other) return me;
return other;
}
public static float Clamp(this float me, float inclusiveFrom, float inclusiveTo)
{
if (me > inclusiveTo) return inclusiveTo;
if (me < inclusiveFrom) return inclusiveFrom;
return me;
}
public static float LerpTo(this float me, float towards, float t)
{
return me * (1 - t) + towards * t;
}
public static float MoveTo(this float me, float towards, float byAmount)
{
if (me < towards)
{
me += byAmount.Abs();
if (me > towards) me = towards;
}
else if (me > towards)
{
me -= byAmount.Abs();
if (me < towards) me = towards;
}
return me;
}
public static float Round(this float a)
{
return (float)System.Math.Round(a);
}
public static float Ceil(this float a)
{
return (float)System.Math.Ceiling(a);
}
public static float Floor(this float a)
{
return (float)System.Math.Floor(a);
}
#endregion
#region float Floor Round Ceil To extenions
public static short RoundToShort(this float a)
{
return (short)System.Math.Round(a);
}
public static short CeilToShort(this float a)
{
return (short)System.Math.Ceiling(a);
}
public static short FloorToShort(this float a)
{
return (short)System.Math.Floor(a);
}
public static short ToShort(this float a)
{
return (short)a;
}
public static ushort RoundToUShort(this float a)
{
return (ushort)System.Math.Round(a);
}
public static ushort CeilToUShort(this float a)
{
return (ushort)System.Math.Ceiling(a);
}
public static ushort FloorToUShort(this float a)
{
return (ushort)System.Math.Floor(a);
}
public static ushort ToUShort(this float a)
{
return (ushort)a;
}
public static int RoundToInt(this float a)
{
return (int)System.Math.Round(a);
}
public static int CeilToInt(this float a)
{
return (int)System.Math.Ceiling(a);
}
public static int FloorToInt(this float a)
{
return (int)System.Math.Floor(a);
}
public static int ToInt(this float a)
{
return (int)a;
}
public static uint RoundToUInt(this float a)
{
return (uint)System.Math.Round(a);
}
public static uint CeilToUInt(this float a)
{
return (uint)System.Math.Ceiling(a);
}
public static uint FloorToUInt(this float a)
{
return (uint)System.Math.Floor(a);
}
public static uint ToUInt(this float a)
{
return (uint)a;
}
public static long RoundToLong(this float a)
{
return (long)System.Math.Round(a);
}
public static long CeilToLong(this float a)
{
return (long)System.Math.Ceiling(a);
}
public static long FloorToLong(this float a)
{
return (long)System.Math.Floor(a);
}
public static long ToLong(this float a)
{
return (long)a;
}
public static ulong RoundToULong(this float a)
{
return (ulong)System.Math.Round(a);
}
public static ulong CeilToULong(this float a)
{
return (ulong)System.Math.Ceiling(a);
}
public static ulong FloorToULong(this float a)
{
return (ulong)System.Math.Floor(a);
}
public static ulong ToULong(this float a)
{
return (ulong)a;
}
#endregion
#region double extensions
public static double Abs(this double a)
{
return System.Math.Abs(a);
}
public static double Pow(this double a, double power)
{
return (double)System.Math.Pow(a, power);
}
public static double Max(this double me, double other)
{
if (me > other) return me;
return other;
}
public static double Min(this double me, double other)
{
if (me < other) return me;
return other;
}
public static double Clamp(this double me, float inclusiveFrom, double inclusiveTo)
{
if (me > inclusiveTo) return inclusiveTo;
if (me < inclusiveFrom) return inclusiveFrom;
return me;
}
public static double Round(this double a)
{
return (double)System.Math.Round(a);
}
public static double Ceil(this double a)
{
return (double)System.Math.Ceiling(a);
}
public static double Floor(this double a)
{
return (double)System.Math.Floor(a);
}
#endregion
#region double Floor Round Ceil To extenions
public static short RoundToShort(this double a)
{
return (short)System.Math.Round(a);
}
public static short CeilToShort(this double a)
{
return (short)System.Math.Ceiling(a);
}
public static short FloorToShort(this double a)
{
return (short)System.Math.Floor(a);
}
public static short ToShort(this double a)
{
return (short)a;
}
public static ushort RoundToUShort(this double a)
{
return (ushort)System.Math.Round(a);
}
public static ushort CeilToUShort(this double a)
{
return (ushort)System.Math.Ceiling(a);
}
public static ushort FloorToUShort(this double a)
{
return (ushort)System.Math.Floor(a);
}
public static ushort ToUShort(this double a)
{
return (ushort)a;
}
public static int RoundToInt(this double a)
{
return (int)System.Math.Round(a);
}
public static int CeilToInt(this double a)
{
return (int)System.Math.Ceiling(a);
}
public static int FloorToInt(this double a)
{
return (int)System.Math.Floor(a);
}
public static int ToInt(this double a)
{
return (int)a;
}
public static uint RoundToUInt(this double a)
{
return (uint)System.Math.Round(a);
}
public static uint CeilToUInt(this double a)
{
return (uint)System.Math.Ceiling(a);
}
public static uint FloorToUInt(this double a)
{
return (uint)System.Math.Floor(a);
}
public static uint ToUInt(this double a)
{
return (uint)a;
}
public static long RoundToLong(this double a)
{
return (long)System.Math.Round(a);
}
public static long CeilToLong(this double a)
{
return (long)System.Math.Ceiling(a);
}
public static long FloorToLong(this double a)
{
return (long)System.Math.Floor(a);
}
public static long ToLong(this double a)
{
return (long)a;
}
public static ulong RoundToULong(this double a)
{
return (ulong)System.Math.Round(a);
}
public static ulong CeilToULong(this double a)
{
return (ulong)System.Math.Ceiling(a);
}
public static ulong FloorToULong(this double a)
{
return (ulong)System.Math.Floor(a);
}
public static ulong ToULong(this double a)
{
return (ulong)a;
}
#endregion
#region int extensions
public static int Abs(this int val)
{
if (val >= 0) return val;
return -val;
}
public static int Max(this int me, int other)
{
if (me > other) return me;
return other;
}
public static int Min(this int me, int other)
{
if (me < other) return me;
return other;
}
public static int Clamp(this int me, int inclusiveFrom, int inclusiveTo)
{
if (me > inclusiveTo) return inclusiveTo;
if (me < inclusiveFrom) return inclusiveFrom;
return me;
}
#endregion
#region string extensions
static readonly Regex oneOrMoreWhiteSpaces = new Regex(@"^\s+$");
/// <summary>
/// Counts the amount of occurence of <paramref name="needle"/> in <paramref name="haystack"/>;
/// </summary>
/// <param name="haystack"></param>
/// <param name="needle"></param>
/// <returns></returns>
public static int Count(this string haystack, char needle)
{
int count = 0;
for (int i = 0; i < haystack.Length; i++)
if (haystack[i] == needle)
count++;
return count;
}
public static string Replace(this string str, string oldValue, string newValue, StringComparison comparison)
{
if (oldValue == null)
throw new ArgumentNullException("oldValue");
if (oldValue.Length == 0)
throw new ArgumentException("String cannot be of zero length.", "oldValue");
StringBuilder sb = null;
int startIndex = 0;
int foundIndex = str.IndexOf(oldValue, comparison);
while (foundIndex != -1)
{
if (sb == null)
sb = new StringBuilder(str.Length + (newValue != null ? Math.Max(0, 5 * (newValue.Length - oldValue.Length)) : 0));
sb.Append(str, startIndex, foundIndex - startIndex);
sb.Append(newValue);
startIndex = foundIndex + oldValue.Length;
foundIndex = str.IndexOf(oldValue, startIndex, comparison);
}
if (startIndex == 0)
return str;
sb.Append(str, startIndex, str.Length - startIndex);
return sb.ToString();
}
public static string RemoveFromEnd(this string s, int count)
{
return s.Substring(0, s.Length - count);
}
public static string RemoveFromBegin(this string s, int count)
{
return s.Substring(count);
}
public static string TakeFromBegin(this string s, int count)
{
return s.Substring(0, count);
}
public static string TakeFromEnd(this string s, int count)
{
return s.Substring(s.Length - count, count);
}
public static bool IsNullOrEmpty(this string s)
{
return string.IsNullOrEmpty(s);
}
public static bool IsWhiteSpace(this string s)
{
return oneOrMoreWhiteSpaces.IsMatch(s);
}
public static bool IsNullOrWhiteSpace(this string s)
{
return s == null || IsWhiteSpace(s);
}
public static bool IsNullOrEmptyOrWhiteSpace(this string s)
{
return s == null || s.Length == 0 || IsWhiteSpace(s);
}
public static string RemoveWhiteSpaces(this string str)
{
return oneOrMoreWhiteSpaces.Replace(str, string.Empty);
}
public static string TakeStringBetween(this string str, string start, string end, StringComparison comparison = StringComparison.InvariantCulture)
{
var startIndex = str.IndexOf(start, comparison);
if (startIndex == -1) throw new Exception("start string:'" + start + "' was not found in:'" + str + "'");
startIndex += start.Length;
var endIndex = str.IndexOf(end, startIndex);
if (startIndex > endIndex) throw new Exception("start string:'" + start + "' is after end string: '" + end + "' in: '" + str + "'");
if (endIndex == -1) throw new Exception("end string:'" + end + "' was not found in:'" + str + "'");
return str.Substring(startIndex, endIndex - startIndex);
}
public static string TakeStringBetweenLast(this string str, string start, string end, StringComparison comparison = StringComparison.InvariantCulture)
{
var startIndex = str.LastIndexOf(start, comparison);
if (startIndex == -1) throw new Exception("start string:'" + start + "' was not found in:'" + str + "'");
startIndex += start.Length;
var endIndex = str.LastIndexOf(end);
if (startIndex > endIndex) throw new Exception("start string:'" + start + "' is after end string: '" + end + "' in: '" + str + "'");
if (endIndex == -1) throw new Exception("end string:'" + end + "' was not found in:'" + str + "'");
return str.Substring(startIndex, endIndex - startIndex);
}
public static string TakeStringAfter(this string str, string start, StringComparison comparison = StringComparison.InvariantCulture)
{
var startIndex = str.IndexOf(start, comparison);
if (startIndex == -1) throw new Exception("start string:'" + start + "' was not found in:'" + str + "'");
startIndex += start.Length;
return str.RemoveFromBegin(startIndex);
}
public static string TakeStringAfterLast(this string str, string start, StringComparison comparison = StringComparison.InvariantCulture)
{
var startIndex = str.LastIndexOf(start, comparison);
if (startIndex == -1) throw new Exception("start string:'" + start + "' was not found in:'" + str + "'");
startIndex += start.Length;
return str.RemoveFromBegin(startIndex);
}
public static string TakeStringBefore(this string str, string end, StringComparison comparison = StringComparison.InvariantCulture)
{
var endIndex = str.IndexOf(end, comparison);
if (endIndex == -1) throw new Exception("end string:'" + end + "' was not found in:'" + str + "'");
return str.Substring(0, endIndex);
}
public static string TakeStringBeforeLast(this string str, string end, StringComparison comparison = StringComparison.InvariantCulture)
{
var endIndex = str.LastIndexOf(end, comparison);
if (endIndex == -1) throw new Exception("end string:'" + end + "' was not found in:'" + str + "'");
return str.Substring(0, endIndex);
}
// from http://stackoverflow.com/questions/623104/byte-to-hex-string
/// <summary>
/// Returns byte array from string hex representation, 010204081020 would return {1, 2, 4, 8, 16, 32}.
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static byte[] FromHexString(this string str)
{
if (str.Length == 0 || str.Length % 2 != 0)
return new byte[0];
byte[] buffer = new byte[str.Length / 2];
char c;
for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
{
// Convert first half of byte
c = str[sx];
buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0')) << 4);
// Convert second half of byte
c = str[++sx];
buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0'));
}
return buffer;
}
//from http://stackoverflow.com/questions/5154970/how-do-i-create-a-hashcode-in-net-c-for-a-string-that-is-safe-to-store-in-a
public static int GetPlatformIndependentHashCode(this string text)
{
if (text == null) return 0;
if (text == string.Empty) return 1;
unchecked
{
int hash = 23;
foreach (char c in text)
{
hash = hash * 31 + c;
}
return hash;
}
}
/// <summary>
/// Number of changes needed to turn one string into another.
/// Taken from https://www.dotnetperls.com/levenshtein
/// </summary>
/// <param name="s"></param>
/// <param name="t"></param>
/// <returns></returns>
public static int LevenshteinDistanceTo(this string s, string t)
{
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
// Step 1
if (n == 0) return m;
if (m == 0) return n;
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++) { }
for (int j = 0; j <= m; d[0, j] = j++) { }
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
#endregion
#region char extensions
public static bool IsWhiteSpace(this char c)
{
return oneOrMoreWhiteSpaces.IsMatch(c.ToString());
}
#endregion
#region Type extensions
/// <summary>
/// Returns first custom attribute from type. Returns null if not found.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="type"></param>
/// <param name="inherit"></param>
/// <returns></returns>
public static T GetCustomAttribute<T>(this Type type, bool inherit) where T : class
{
var attributes = type.GetCustomAttributes(typeof(T), inherit);
if (attributes.Length > 0)
{
return attributes[0] as T;
}
return null;
}
// from http://stackoverflow.com/questions/457676/check-if-a-class-is-derived-from-a-generic-class
public static bool IsSubclassOfRawGeneric(this Type toCheck, Type generic)
{
while (toCheck != null && toCheck != typeof(object))
{
var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
if (generic == cur)
{
return true;
}
toCheck = toCheck.BaseType;
}
return false;
}
// from http://stackoverflow.com/questions/325426/programmatic-equivalent-of-defaulttype
/// <summary>
/// Returns default boxed value for value type System.Type , returns null for non-value types.
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public static object GetDefault(this Type t)
{
Func<object> f = GetDefault_Helper<object>;
return f.Method.GetGenericMethodDefinition().MakeGenericMethod(t).Invoke(null, null);
}
private static T GetDefault_Helper<T>()
{
return default(T);
}
public static bool TryConvertFromString(this Type type, string input, out object obj)
{
try
{
var converter = TypeDescriptor.GetConverter(type);
if (converter != null)
{
obj = converter.ConvertFromInvariantString(input);
return true;
}
}
catch
{
}
obj = null;
return false;
}
#endregion
#region Random extensions
public static float Next(this Random random, float minValue, float maxValue)
{
return minValue + (float)(random.NextDouble() * (maxValue - minValue));
}
public static double Next(this Random random, double minValue, double maxValue)
{
return minValue + (double)(random.NextDouble() * (maxValue - minValue));
}
#endregion
#region DateTime extensions
public struct DateTimeHandler
{
DateTime dateTime;
public DateTimeHandler(DateTime dateTime)
{
this.dateTime = dateTime;
}
public bool InPastComparedTo(DateTime other)
{
return dateTime < other;
}
public bool InFutureComparedTo(DateTime other)
{
return dateTime > other;
}
}
public static DateTimeHandler IsOver(this DateTime dateTime, double days = 0, double hours = 0, double minutes = 0, double seconds = 0, double milliseconds = 0)
{
return new DateTimeHandler(dateTime + TimeSpan.FromDays(days) + TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes) + TimeSpan.FromSeconds(seconds) + TimeSpan.FromMilliseconds(milliseconds));
}
public static DateTimeHandler IsOver(this DateTime dateTime, int days = 0, int hours = 0, int minutes = 0, int seconds = 0, int milliseconds = 0)
{
return new DateTimeHandler(dateTime + new TimeSpan(days, hours, minutes, seconds, milliseconds));
}
public static DateTimeHandler IsUnder(this DateTime dateTime, double days = 0, double hours = 0, double minutes = 0, double seconds = 0, double milliseconds = 0)
{
return new DateTimeHandler(dateTime - (TimeSpan.FromDays(days) + TimeSpan.FromHours(hours) + TimeSpan.FromMinutes(minutes) + TimeSpan.FromSeconds(seconds) + TimeSpan.FromMilliseconds(milliseconds)));
}
public static DateTimeHandler IsUnder(this DateTime dateTime, int days = 0, int hours = 0, int minutes = 0, int seconds = 0, int milliseconds = 0)
{
return new DateTimeHandler(dateTime - new TimeSpan(days, hours, minutes, seconds, milliseconds));
}
public static bool IsInPastComparedTo(this DateTime dateTime, DateTime other)
{
return dateTime < other;
}
public static bool IsInFutureComparedTo(this DateTime dateTime, DateTime other)
{
return dateTime > other;
}
public static bool IsBetween(this DateTime dateTime, DateTime rangeExclusiveFrom, DateTime rangeInclusiveTo)
{
if(rangeExclusiveFrom > rangeInclusiveTo)
{
var t = rangeInclusiveTo;
rangeInclusiveTo = rangeExclusiveFrom;
rangeExclusiveFrom = t;
}
return dateTime > rangeExclusiveFrom && dateTime < rangeInclusiveTo;
}
#endregion
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment