Month: November 2016
Object Extensions
Here is my class of object extensions I use.
using System; using System.IO; using System.Reflection; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; namespace Dahl.Core.Extensions { public static partial class Extensions { public static string AsString( this object source ) { return source as string; } public static DateTime AsDateTime( this object source ) { return (DateTime)source; } public static short AsShort( this object source ) { return (short)source; } public static int AsInt( this object source ) { return (int)source; } public static long AsLong( this object source ) { return (long)source; } public static bool AsBool( this object source ) { return (bool)source; } public static byte AsByte( this object source ) { return (byte)source; } public static DateTime? AsNullableDateTime( this object source ) { return source as DateTime?; } public static short? AsNullableShort( this object source ) { return source as short?; } public static int? AsNullableInt( this object source ) { return source as int?; } public static long? AsNullableLong( this object source ) { return source as long?; } public static bool? AsNullableBool( this object source ) { return source as bool?; } public static byte? AsNullableByte( this object source ) { return (byte?)source; } public static DateTime? AsDateTimeNullable( this object source ) { return source as DateTime?; } public static short? AsShortNullable( this object source ) { return source as short?; } public static int? AsIntNullable( this object source ) { return source as int?; } public static long? AsLongNullable( this object source ) { return source as long?; } public static bool? AsBoolNullable( this object source ) { return source as bool?; } public static byte? AsByteNullable( this object source ) { return (byte?)source; } public static byte AsTinyInt( this object source ) { return (byte)source; } public static byte? AsTinyIntNullable( this object source ) { return (byte?)source; } public static short AsSmallInt( this object source ) { return (short)source; } public static short? AsSmallIntNullable( this object source ) { return (short?)source; } //----------------------------------------------------------------------------------------- /// <summary> /// Copy properties from source object into destination object. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="src">copy data from this object into the specified dst object</param> /// <param name="dst">copy data into this object</param> public static void CopyFrom<T>( this T dst, T src ) { PropertyInfo[] srcProperties = src.GetType().GetProperties( BindingFlags.Public | BindingFlags.Instance ); foreach ( PropertyInfo srcProperty in srcProperties ) { if ( srcProperty.CanRead && srcProperty.CanWrite ) { PropertyInfo dstProperty = dst.GetType().GetProperty( srcProperty.Name ); if ( dstProperty != null ) { object val = srcProperty.GetValue( src, null ); dstProperty.SetValue( dst, val, null ); } } } } //----------------------------------------------------------------------------------------- /// <summary> /// Makes a new object and copies /// </summary> /// <typeparam name="T"></typeparam> /// <param name="S"></param> /// <returns></returns> public static T GetCopy<T>( this T S ) { T newObj = Activator.CreateInstance<T>(); foreach ( PropertyInfo i in newObj.GetType().GetProperties() ) { //"EntitySet" is specific to link and this conditional logic is optional/can be ignored if ( i.CanWrite && i.PropertyType.Name.Contains( "EntitySet" ) == false ) { object value = S.GetType().GetProperty( i.Name ).GetValue( S, null ); i.SetValue( newObj, value, null ); } } return newObj; } //----------------------------------------------------------------------------------------- /// <summary> /// Perform a deep Copy of an object, object must be serializable. /// </summary> /// <typeparam name="T">The type of object being copied.</typeparam> /// <param name="source">The object instance to copy.</param> /// <returns>The copied object.</returns> public static T Clone<T>( this T source ) { if ( !typeof( T ).IsSerializable ) { throw new ArgumentException( "The type must be serializable.", nameof( source ) ); } // Don't serialize a null object, simply return the default for that object if ( object.ReferenceEquals( source, null ) ) { return default( T ); } IFormatter formatter = new BinaryFormatter(); Stream stream = new MemoryStream(); using ( stream ) { formatter.Serialize( stream, source ); stream.Seek( 0, SeekOrigin.Begin ); return (T)formatter.Deserialize( stream ); } } } }
Linq Extensions
Here is my class of linq extensions I use.
This is an example of using the extension in a unit test.
[TestMethod] public void Linq_OrderBy() { List<User> userList = UserList.OrderBy( "FirstName" ).ToList(); Trace.WriteLine( "=== Order By FirstName ascending ===" ); foreach ( User user in userList ) Trace.WriteLine( $"FirstName: {user.FirstName}, LastName: {user.LastName}" ); userList = UserList.OrderBy( "LastName", false ).ToList(); Trace.WriteLine( "=== Order By LastName descending ====" ); foreach ( User user in userList ) Trace.WriteLine( $"FirstName: {user.FirstName}, LastName: {user.LastName}" ); } private static readonly List<User> UserList = new List<User>() { new User { FirstName = "firstName03", LastName= "lastName08" }, new User { FirstName = "firstName07", LastName= "lastName04" }, new User { FirstName = "firstName06", LastName= "lastName05" }, new User { FirstName = "firstName04", LastName= "lastName07" }, new User { FirstName = "firstName10", LastName= "lastName01" }, new User { FirstName = "firstName09", LastName= "lastName02" }, new User { FirstName = "firstName08", LastName= "lastName03" }, new User { FirstName = "firstName05", LastName= "lastName06" }, new User { FirstName = "firstName02", LastName= "lastName09" }, new User { FirstName = "firstName01", LastName= "lastName10" } };
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; namespace Dahl.Core.Extensions { public static partial class Extensions { //----------------------------------------------------------------------------------------- /// <summary> /// Sorts the elements of a sequence according to a key. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TKey"></typeparam> /// <param name="source"></param> /// <param name="keySelector"></param> /// <param name="descending"></param> /// <returns></returns> public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>( this IEnumerable<TSource> source, Func<TSource, TKey> keySelector, bool descending ) { if ( descending ) return source.OrderByDescending( keySelector ); return source.OrderBy( keySelector ); } //----------------------------------------------------------------------------------------- /// <summary> /// /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TKey"></typeparam> /// <param name="source"></param> /// <param name="keySelector"></param> /// <param name="descending"></param> /// <returns></returns> public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>( this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool descending ) { return descending ? source.OrderByDescending( keySelector ) : source.OrderBy( keySelector ); } //----------------------------------------------------------------------------------------- /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="sortExpression"></param> /// <param name="sortAscending"></param> /// <returns></returns> public static IQueryable<T> OrderBy<T>( this IQueryable<T> list, string sortExpression, bool sortAscending = true ) { return sortAscending ? list.OrderBy( f => OrderFunc( f, sortExpression ) ) : list.OrderByDescending( f => OrderFunc( f, sortExpression ) ); } //----------------------------------------------------------------------------------------- /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="list"></param> /// <param name="sortExpression"></param> /// <param name="sortAscending"></param> /// <returns></returns> public static IEnumerable<T> OrderBy<T>( this IEnumerable<T> list, string sortExpression, bool sortAscending = true ) { return sortAscending ? list.OrderBy( f => OrderFunc( f, sortExpression ) ) : list.OrderByDescending( f => OrderFunc( f, sortExpression ) ); } //----------------------------------------------------------------------------------------- /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <param name="propertyName"></param> /// <returns></returns> public static object GetChildObject<T>( T obj, string propertyName ) { Type t = obj.GetType(); PropertyInfo prop = t.GetProperty( propertyName ); if ( prop == null ) { string msg = $"PropertyName \"{propertyName}\" is not defined in class \"{obj.GetType().FullName}\"."; throw new ArgumentException( msg ); } return prop.GetValue( obj, null ) ?? Activator.CreateInstance( prop.PropertyType ); } //----------------------------------------------------------------------------------------- /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="obj"></param> /// <param name="propertyName"></param> /// <returns></returns> private static object OrderFunc<T>( T obj, string propertyName ) { string propName = propertyName; object newObj = obj; if ( propertyName.Contains( '.' ) ) { // the requested property is contained in a child object string[] parts = propertyName.Split( '.' ); int numParts = parts.Length - 1; for ( int i = 0; i < numParts; i++ ) newObj = GetChildObject( newObj, parts[i] ); propName = parts[numParts]; } PropertyInfo propertyGetter = newObj.GetType() .GetProperty( propName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase ); if ( propertyGetter == null ) { string msg = @"Sort Expression could not find property name provided<br />" + $"PropertyName: {propertyName}"; throw new ArgumentException( msg ); } return propertyGetter.GetValue( newObj, null ); } //----------------------------------------------------------------------------------------- /// <summary> /// /// </summary> /// <typeparam name="TSrc"></typeparam> /// <typeparam name="TKey"></typeparam> /// <param name="src"></param> /// <param name="selector"></param> /// <returns></returns> public static IEnumerable<TSrc> DistinctBy<TSrc, TKey>( this IEnumerable<TSrc> src, Func<TSrc, TKey> selector ) { HashSet<TKey> keys = new HashSet<TKey>(); return src.Where( element => keys.Add( selector( element ) ) ); } } }
String Extensions
Here is my class of string extensions I like to use. It allows me to write code that is easier for me to read. For me, I find the following two examples a lot easier to read and allows me to be more consistent in writing code.
// Test if two string are not equal string s1 = "this is string #1"; string s2 = "this is string #2"; if ( s1.IsNotEqualIgnoreCase( s2 ) ) DoSomething();
// convert a string to an integer string s = "12356"; int x = s.ToInt();
C# class Extensions:
using System; using System.Globalization; using System.Text.RegularExpressions; namespace Dahl.Core.Extensions { public static class StringExt { ///---------------------------------------------------------------------------------------- /// <summary> /// Trims whitespace from the string. /// </summary> /// <param name="source"></param> /// <returns></returns> public static string TrimWhiteSpace( this string source ) { if ( string.IsNullOrEmpty( source ) ) return string.Empty; return source.Trim(); } ///---------------------------------------------------------------------------------------- /// <summary> /// Determines whether two T:string objects have the same value ignoring case, /// uses StringComparison.OrdinalIgnoreCase /// </summary> /// <param name="source">the string to compare</param> /// <param name="val">the value to compare</param> /// <returns></returns> public static bool IsEqualIgnoreCase( this string source, string val ) { if ( string.IsNullOrEmpty( source ) && string.IsNullOrEmpty( val ) ) return false; if ( string.IsNullOrEmpty( source ) ) return false; return string.Equals( source, val, StringComparison.OrdinalIgnoreCase ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Determines whether 2 specified T:String objects have the same value ignoring case, /// uses StringComparison.OrdinalIgnoreCase /// </summary> /// <param name="source">the string to compare</param> /// <param name="val">the value to compare</param> /// <returns></returns> public static bool IsNotEqual( this string source, string val ) { if ( string.IsNullOrEmpty( source ) && !string.IsNullOrEmpty( val ) ) return true; if ( string.IsNullOrEmpty( val ) ) return true; return !string.Equals( source, val ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Determines whether 2 specified T:String objects have the same value ignoring case, /// uses StringComparison.OrdinalIgnoreCase /// </summary> /// <param name="source">the string to compare</param> /// <param name="val">the value to compare</param> /// <returns></returns> public static bool IsNotEqualIgnoreCase( this string source, string val ) { if ( string.IsNullOrEmpty( source ) && !string.IsNullOrEmpty( val ) ) return true; if ( string.IsNullOrEmpty( val ) ) return true; return !string.Equals( source, val, StringComparison.OrdinalIgnoreCase ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Returns a value indicating whether the specified String object occurs within this string ignoring case, /// uses StringComparison.OrdinalIgnoreCase /// </summary> /// <param name="source">the string to compare</param> /// <param name="val">the value to find</param> /// <returns></returns> public static bool ContainsIgnoreCase( this string source, string val ) { if ( string.IsNullOrEmpty( source ) || string.IsNullOrEmpty( val ) ) return false; return source.IndexOf( val, StringComparison.OrdinalIgnoreCase ) >= 0; } ///---------------------------------------------------------------------------------------- /// <summary> /// Returns a value indicating whether the specified String object contains anything /// </summary> /// <param name="source">the string to compare</param> /// <returns></returns> public static bool IsNullOrEmpty( this string source ) { return string.IsNullOrEmpty( source ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Returns a value indicating whether the specified String object contains anything /// </summary> /// <param name="source">the string to compare</param> /// <returns></returns> public static bool IsNotNullOrEmpty( this string source ) { return !string.IsNullOrEmpty( source ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Determines whether the beginning of this string instance matches the specified string ignoring case, /// uses StringComparison.OrdinalIgnoreCase /// </summary> /// <param name="source">the string to compare</param> /// <param name="val">the value to find</param> /// <returns></returns> public static bool StartsWithIgnoreCase( this string source, string val ) { if ( string.IsNullOrEmpty( source ) || string.IsNullOrEmpty( val ) ) return false; return source.StartsWith( val, StringComparison.OrdinalIgnoreCase ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Determines whether the end of this string instance matches the specified string ignoring case, /// uses StringComparison.OrdinalIgnoreCase /// </summary> /// <param name="source">the string to compare</param> /// <param name="val">the value to find</param> /// <returns></returns> public static bool EndsWithIgnoreCase( this string source, string val ) { if ( string.IsNullOrEmpty( source ) || string.IsNullOrEmpty( val ) ) return false; return source.EndsWith( val, StringComparison.OrdinalIgnoreCase ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Replaces the old value with the specified new value ignoring case. /// </summary> /// <param name="source"></param> /// <param name="oldValue">The part of the string to be replaced by the newValue</param> /// <param name="newValue">The new string to replace the old value</param> /// <returns></returns> public static string ReplaceIgnoreCase( this string source, string oldValue, string newValue ) { string s; try { if ( source == null ) source = string.Empty; if ( oldValue == null ) oldValue = string.Empty; s = Regex.Replace( source, oldValue, newValue, RegexOptions.IgnoreCase ); } catch ( Exception ) { s = oldValue; } return s; } ///---------------------------------------------------------------------------------------- /// <summary> /// /// </summary> /// <param name="source"></param> /// <returns></returns> public static string ToString( this string source ) { if ( source == null ) return string.Empty; return source.ToString( CultureInfo.InvariantCulture ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Returns a string up to the maxLen specified. /// </summary> /// <param name="source"></param> /// <param name="maxLen">The maximum length of the sting</param> /// <returns></returns> public static string ToString( this string source, int maxLen ) { if ( string.IsNullOrEmpty( source ) ) return string.Empty; if ( source.Length > maxLen ) return source.Substring( 0, maxLen ); return source.TrimEnd(); } ///---------------------------------------------------------------------------------------- /// <summary> /// Takes a string and if its length is greater than maxLen it trims it to maxLen-3 and /// appends three periods to the string. /// </summary> /// <param name="source">the string to compare</param> /// <param name="maxLen">maximum length of string to return</param> /// <returns></returns> public static string ToEllipsis( this string source, int maxLen ) { if ( string.IsNullOrEmpty( source ) ) return string.Empty; maxLen -= 3; if ( source.Length > maxLen ) return string.Format( "{0}...", source.Substring( 0, maxLen ) ); return source.TrimEnd(); } ///---------------------------------------------------------------------------------------- /// <summary> /// If possible makes a Guid from the string provided, otherwise it returns an Empty Guid. /// </summary> /// <param name="source"></param> /// <returns></returns> public static Guid ToGuid( this string source ) { Guid result; try { result = new Guid( source ); } catch ( Exception ) { result = Guid.Empty; } return result; } ///---------------------------------------------------------------------------------------- /// <summary> /// Converts string to title case by first changing all characters to lower case. /// </summary> /// <param name="source"></param> /// <returns></returns> public static string ToTitleCase( this string source ) { CultureInfo cultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture; return cultureInfo.TextInfo.ToTitleCase( source.ToLower() ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Convert string to DateTime, if null or empty then returns defaultValue /// </summary> /// <param name="source"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static DateTime ToDateTime( this string source, DateTime defaultValue = default( DateTime ) ) { if ( string.IsNullOrEmpty( source ) ) return defaultValue; DateTime result; if ( !DateTime.TryParse( source, out result ) ) result = defaultValue; return result; } ///---------------------------------------------------------------------------------------- /// <summary> /// Convert string to DateTime, if null or empty then returns defaultValue /// </summary> /// <param name="source"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static DateTime ToDate( this string source, DateTime defaultValue = default( DateTime ) ) { if ( string.IsNullOrEmpty( source ) ) return defaultValue; DateTime result; if ( !DateTime.TryParse( source, out result ) ) result = defaultValue; return new DateTime( result.Year, result.Month, result.Day ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Converts string into a boolean value. /// </summary> /// <param name="source">Valid values are "f" or "false" and "t" or "true"</param> /// <param name="defaultValue">If parameter is not specified, false is returned.</param> /// <returns></returns> public static bool ToBool( this string source, bool defaultValue = default( bool ) ) { if ( string.IsNullOrEmpty( source ) ) return defaultValue; string s = source.ToLower().Trim(); if ( s.Equals( "false" ) || s.Equals( "f" ) || s == "0" ) return false; if ( s.Equals( "true" ) || s.Equals( "t" ) || s == "1" ) return true; return defaultValue; } ///---------------------------------------------------------------------------------------- /// <summary> /// Convert string to short, if null or empty then returns defaultValue /// </summary> /// <param name="source"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static short ToShort( this string source, short defaultValue = default( short ) ) { if ( string.IsNullOrEmpty( source ) ) return defaultValue; short result; source = source.Replace( ",", "" ); if ( short.TryParse( source, out result ) ) return result; return defaultValue; } ///---------------------------------------------------------------------------------------- /// <summary> /// Convert string to Int, if null or empty then returns defaultValue /// </summary> /// <param name="source"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static int ToInt( this string source, int defaultValue = default( int ) ) { if ( string.IsNullOrEmpty( source ) ) return defaultValue; int result; source = source.Replace( ",", "" ); if ( int.TryParse( source, out result ) ) return result; return defaultValue; } ///---------------------------------------------------------------------------------------- /// <summary> /// Trys to converts an object to an integer /// </summary> /// <param name="source"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static int ToInt( this object source, int defaultValue = default( int ) ) { int target = defaultValue; if ( source is string ) target = IntParse( source.ToString() ); else if ( source is int ) target = (int)source; return target; } ///---------------------------------------------------------------------------------------- /// <summary> /// Converts a string to an integer /// </summary> /// <param name="source">The string to parse</param> /// <param name="defaultValue">If provided, a value to return if the string cannot be parsed, /// if not provided zero will be used as the default value</param> /// <returns>The parsed value if string represents a legal integer, otherwise the default value</returns> public static int IntParse( this string source, int defaultValue = default( int ) ) { int target; int.TryParse( source, out target ); return target; } ///---------------------------------------------------------------------------------------- /// <summary> /// Convert string to long, if null or empty then returns defaultValue /// </summary> /// <param name="source"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static long ToLong( this string source, long defaultValue = default( long ) ) { if ( string.IsNullOrEmpty( source ) ) return defaultValue; long result; source = source.Replace( ",", "" ); if ( long.TryParse( source, out result ) ) return result; return defaultValue; } ///---------------------------------------------------------------------------------------- /// <summary> /// Convert string to double, if null or empty then returns defaultValue /// </summary> /// <param name="source"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static double ToDouble( this string source, double defaultValue = default( double ) ) { if ( string.IsNullOrEmpty( source ) ) return defaultValue; double result; source = source.Replace( ",", "" ); if ( double.TryParse( source, out result ) ) return result; return defaultValue; } ///---------------------------------------------------------------------------------------- /// <summary> /// Convert string to float, if null or empty then returns defaultValue /// </summary> /// <param name="source"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static float ToFloat( this string source, float defaultValue = default( float ) ) { if ( string.IsNullOrEmpty( source ) ) return defaultValue; float result; source = source.Replace( ",", "" ); if ( float.TryParse( source, out result ) ) return result; return defaultValue; } ///---------------------------------------------------------------------------------------- /// <summary> /// Converts string to decimal, if null or empty then uses default value /// </summary> /// <param name="source"></param> /// <param name="defaultValue"></param> /// <returns></returns> public static decimal ToDecimal( this string source, decimal defaultValue = default( decimal ) ) { if ( string.IsNullOrEmpty( source ) ) return defaultValue; decimal result; source = source.Replace( ",", "" ); if ( decimal.TryParse( source, out result ) ) return result; return defaultValue; } ///---------------------------------------------------------------------------------------- /// <summary> /// /// </summary> private static readonly Regex NonDigit = new Regex( "\\D" ); ///---------------------------------------------------------------------------------------- /// <summary> /// Returns only Digits /// </summary> /// <param name="number"></param> /// <returns></returns> public static string OnlyDigits( this string number ) { return NonDigit.Replace( number, string.Empty ); } ///---------------------------------------------------------------------------------------- /// <summary> /// Returns a short date string /// </summary> /// <param name="date"></param> /// <returns></returns> public static string ToShortDateString( this DateTime? date ) { return date?.ToShortDateString() ?? string.Empty; } ///---------------------------------------------------------------------------------------- /// <summary> /// Returns a long date string /// </summary> /// <param name="date"></param> /// <returns></returns> public static string ToLongDateString( this DateTime? date ) { return date?.ToLongDateString() ?? string.Empty; } ///---------------------------------------------------------------------------------------- /// <summary> /// Provide a string to test pattern to see if email address is probably in a valid format. /// </summary> /// <param name="source"></param> /// <returns></returns> public static bool IsValidEmailFormat( this string source ) { const string pattern = @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$"; return Regex.IsMatch( source, pattern ); } } }