Quelle est l’utilisation la meilleure ou la plus intéressante des méthodes d’extension que vous avez vues?

Je commence à vraiment aimer les méthodes de vulgarisation … Je me demandais si quelqu’un l’avait trouvée et qui avait vraiment soufflé, ou si elle avait trouvé l’intelligence.

Un exemple que j’ai écrit aujourd’hui:

Modifié en raison des commentaires d’autres utilisateurs:

public static IEnumerable To(this int fromNumber, int toNumber) { while (fromNumber < toNumber) { yield return fromNumber; fromNumber++; } } 

Cela permet d’écrire une boucle for en boucle foreach:

 foreach (int x in 0.To(16)) { Console.WriteLine(Math.Pow(2, x).ToSsortingng()); } 

J’ai hâte de voir d’autres exemples! Prendre plaisir!

La solution complète est trop grande pour être placée ici, mais j’ai écrit une série de méthodes d’extension qui vous permettraient de convertir facilement un DataTable en un fichier CSV.

 public static Ssortingng ToCSV(this DataTable dataTable) { return dataTable.ToCSV(null, COMMA, true); } public static Ssortingng ToCSV(this DataTable dataTable, Ssortingng qualifier) { return dataTable.ToCSV(qualifier, COMMA, true); } private static Ssortingng ToCSV(this DataTable dataTable, Ssortingng qualifier, Ssortingng delimiter, Boolean includeColumnNames) { if (dataTable == null) return null; if (qualifier == delimiter) { throw new InvalidOperationException( "The qualifier and the delimiter are identical. This will cause the CSV to have collisions that might result in data being parsed incorrectly by another program."); } var sbCSV = new SsortingngBuilder(); var delimiterToUse = delimiter ?? COMMA; if (includeColumnNames) sbCSV.AppendLine(dataTable.Columns.GetHeaderLine(qualifier, delimiterToUse)); foreach (DataRow row in dataTable.Rows) { sbCSV.AppendLine(row.ToCSVLine(qualifier, delimiterToUse)); } return sbCSV.Length > 0 ? sbCSV.ToSsortingng() : null; } private static Ssortingng ToCSVLine(this DataRow dataRow, Ssortingng qualifier, Ssortingng delimiter) { var colCount = dataRow.Table.Columns.Count; var rowValues = new Ssortingng[colCount]; for (var i = 0; i < colCount; i++) { rowValues[i] = dataRow[i].Qualify(qualifier); } return String.Join(delimiter, rowValues); } private static String GetHeaderLine(this DataColumnCollection columns, String qualifier, String delimiter) { var colCount = columns.Count; var colNames = new String[colCount]; for (var i = 0; i < colCount; i++) { colNames[i] = columns[i].ColumnName.Qualify(qualifier); } return String.Join(delimiter, colNames); } private static String Qualify(this Object target, String qualifier) { return qualifier + target + qualifier; } 

À la fin de la journée, vous pourriez l'appeler ainsi:

 someDataTable.ToCSV(); //Plain old CSV someDataTable.ToCSV("\""); //Double quote qualifier someDataTable.ToCSV("\"", "\t"); //Tab delimited 

C’est un jeu que j’ai reçu récemment:

 public static IDisposable Tag(this HtmlHelper html, ssortingng tagName) { if (html == null) throw new ArgumentNullException("html"); Action a = tag => html.Write(Ssortingng.Format(tag, tagName)); a("<{0}>"); return new Memento(() => a("")); } 

Utilisé comme:

 using (Html.Tag("ul")) { this.Model.ForEach(item => using(Html.Tag("li")) Html.Write(item)); using(Html.Tag("li")) Html.Write("new"); } 

Memento est un cours pratique:

 public sealed class Memento : IDisposable { private bool Disposed { get; set; } private Action Action { get; set; } public Memento(Action action) { if (action == null) throw new ArgumentNullException("action"); Action = action; } void IDisposable.Dispose() { if (Disposed) throw new ObjectDisposedException("Memento"); Disposed = true; Action(); } } 

Et pour compléter les dépendances:

 public static void Write(this HtmlHelper html, ssortingng content) { if (html == null) throw new ArgumentNullException("html"); html.ViewContext.HttpContext.Response.Write(content); } 

Je ne suis pas un fan de l’interface INotifyPropertyChanged qui requirejs que les noms de propriété soient transmis en tant que chaînes. Je veux une méthode fortement typée pour vérifier au moment de la compilation que je ne fais que générer et gérer des modifications de propriétés pour les propriétés existantes. J’utilise ce code pour faire cela:

 public static class INotifyPropertyChangedExtensions { public static ssortingng ToPropertyName(this Expression> @this) { var @return = ssortingng.Empty; if (@this != null) { var memberExpression = @this.Body as MemberExpression; if (memberExpression != null) { @return = memberExpression.Member.Name; } } return @return; } } 

Dans les classes qui implémentent INotifyPropertyChanged cette méthode d’assistance:

 protected void NotifySetProperty(ref T field, T value, Expression> propertyExpression) { if (field == null ? value != null : !field.Equals(value)) { field = value; this.NotifyPropertyChanged(propertyExpression.ToPropertyName()); } } 

Alors que finalement je peux faire ce genre de chose:

 private ssortingng _name; public ssortingng Name { get { return _name; } set { this.NotifySetProperty(ref _name, value, () => this.Name); } } 

Il est fortement typé et je ne déclenche que des événements pour les propriétés qui changent réellement leur valeur.

Eh bien, ce n’est pas tout à fait intelligent, mais j’ai modifié les méthodes —- OrDefault afin de pouvoir spécifier un élément par défaut au lieu de vérifier la valeur null plus tard dans votre code:

  public static T SingleOrDefault ( this IEnumerable source, Func action, T theDefault ) { T item = source.SingleOrDefault(action); if (item != null) return item; return theDefault; } 

Son incroyable simple mais aide vraiment à nettoyer ces contrôles nuls. Mieux utilisé lorsque votre interface utilisateur attend une liste d’éléments X, comme un système de tournoi ou des emplacements de joueurs, et que vous souhaitez afficher des “sièges vides”.

Usage:

  return jediList.SingleOrDefault( j => j.LightsaberColor == "Orange", new Jedi() { LightsaberColor = "Orange", Name = "DarthNobody"); 

En voici un que j’ai piraté, alors n’hésitez pas à y trouver des trous. Il prend une liste (ordonnée) d’entiers et renvoie une liste de chaînes de plages contiguës. par exemple:

 1,2,3,7,10,11,12 --> "1-3","7","10-12" 

La fonction (dans une classe statique):

 public static IEnumerable IntRanges(this IEnumerable numbers) { int rangeStart = 0; int previous = 0; if (!numbers.Any()) yield break; rangeStart = previous = numbers.FirstOrDefault(); foreach (int n in numbers.Skip(1)) { if (n - previous > 1) // sequence break - yield a sequence { if (previous > rangeStart) { yield return ssortingng.Format("{0}-{1}", rangeStart, previous); } else { yield return rangeStart.ToSsortingng(); } rangeStart = n; } previous = n; } if (previous > rangeStart) { yield return ssortingng.Format("{0}-{1}", rangeStart, previous); } else { yield return rangeStart.ToSsortingng(); } } 

Exemple d’utilisation:

 this.WeekDescription = ssortingng.Join(",", from.WeekPattern.WeekPatternToInts().IntRanges().ToArray()); 

Ce code est utilisé pour convertir les données d’une application d’horodatage DailyWTF. WeekPattern est un masque de bits stocké dans une chaîne “0011011100 …”. WeekPatternToInts () convertit cela en IEnumerable , dans ce cas [3,4,6,7,8], qui devient “3-4,6-8”. Il fournit à l’utilisateur une description compacte des plages de semaines académiques sur lesquelles se déroule une conférence.

Deux méthodes que j’aime utiliser sont les méthodes d’extension InsertWhere > et RemoveWhere > que j'ai écrites. Travailler avec ObservableCollections dans WPF et Silverlight J'ai souvent besoin de modifier les listes ordonnées sans les recréer. Ces méthodes me permettent d'insérer et de supprimer selon un Func fourni, de sorte que .OrderBy () n'a pas besoin d'être appelé à nouveau.

  ///  /// Removes all items from the provided  that match the expression. ///  /// The class type of the list items. /// The list to remove items from. /// The predicate expression to test against. public static void RemoveWhere(this IList list, Func predicate) { T[] copy = new T[] { }; Array.Resize(ref copy, list.Count); list.CopyTo(copy, 0); for (int i = copy.Length - 1; i >= 0; i--) { if (predicate(copy[i])) { list.RemoveAt(i); } } } ///  /// Inserts an Item into a list at the first place that the  expression fails. If it is true in all cases, then the item is appended to the end of the list. ///  ///  ///  ///  /// The sepcified function that determines when the  should be added.  public static void InsertWhere(this IList list, T obj, Func predicate) { for (int i = 0; i < list.Count; i++) { // When the function first fails it inserts the obj paramiter. // For example, in a list myList of ordered Int32's {1,2,3,4,5,10,12} // Calling myList.InsertWhere( 8, x => 8 > x) inserts 8 once the list item becomes greater then or equal to it. if(!predicate(list[i])) { list.Insert(i, obj); return; } } list.Add(obj); } 

Modifier:
Talljoe a apporté des améliorations significatives à RemoveWhere / RemoveAll, que j'avais rapidement construit. Avec les éléments ~ 3mill supprimant un tiers, la nouvelle version ne prend que ~ 50 millisecondes (moins de 10 si elle peut appeler List.RemoveAll!), Contrairement aux multiples secondes de RemoveWhere (j'en ai eu marre d'attendre).

Voici sa version grandement améliorée, merci encore!

  public static void RemoveAll(this IList instance, Predicate predicate) { if (instance == null) throw new ArgumentNullException("instance"); if (predicate == null) throw new ArgumentNullException("predicate"); if (instance is T[]) throw new NotSupportedException(); var list = instance as List; if (list != null) { list.RemoveAll(predicate); return; } int writeIndex = 0; for (int readIndex = 0; readIndex < instance.Count; readIndex++) { var item = instance[readIndex]; if (predicate(item)) continue; if (readIndex != writeIndex) { instance[writeIndex] = item; } ++writeIndex; } if (writeIndex != instance.Count) { for (int deleteIndex = instance.Count - 1; deleteIndex >= writeIndex; --deleteIndex) { instance.RemoveAt(deleteIndex); } } } 

J’ai diverses méthodes d’extension .Debugify utiles pour .Debugify des objects dans un fichier journal. Par exemple, voici mon dictionnaire debugify (je les ai pour List, Datatable, param array, etc.):

 public static ssortingng Debugify(this Dictionary dictionary) { ssortingng Result = ""; if (dictionary.Count > 0) { SsortingngBuilder ResultBuilder = new SsortingngBuilder(); int Counter = 0; foreach (KeyValuePair Entry in dictionary) { Counter++; ResultBuilder.AppendFormat("{0}: {1}, ", Entry.Key, Entry.Value); if (Counter % 10 == 0) ResultBuilder.AppendLine(); } Result = ResultBuilder.ToSsortingng(); } return Result; } 

Et en voici une pour DbParameterCollection (utile pour transférer les appels de firebase database vers le fichier journal):

 public static ssortingng Debugify(this DbParameterCollection parameters) { List ParameterValuesList = new List(); foreach (DbParameter Parameter in parameters) { ssortingng ParameterName, ParameterValue; ParameterName = Parameter.ParameterName; if (Parameter.Direction == ParameterDirection.ReturnValue) continue; if (Parameter.Value == null || Parameter.Value.Equals(DBNull.Value)) ParameterValue = "NULL"; else { switch (Parameter.DbType) { case DbType.Ssortingng: case DbType.Date: case DbType.DateTime: case DbType.Guid: case DbType.Xml: ParameterValue = "'" + Parameter .Value .ToSsortingng() .Replace(Environment.NewLine, "") .Left(80, "...") + "'"; // Left... is another nice one break; default: ParameterValue = Parameter.Value.ToSsortingng(); break; } if (Parameter.Direction != ParameterDirection.Input) ParameterValue += " " + Parameter.Direction.ToSsortingng(); } ParameterValuesList.Add(ssortingng.Format("{0}={1}", ParameterName, ParameterValue)); } return ssortingng.Join(", ", ParameterValuesList.ToArray()); } 

Exemple de résultat:

 Log.DebugFormat("EXEC {0} {1}", procName, params.Debugify); // EXEC spProcedure @intID=5, @nvName='Michael Haren', @intRefID=11 OUTPUT 

Notez que si vous appelez cela après vos appels de firebase database, vous obtiendrez également les parameters de sortie. J’appelle ceci sur une ligne qui inclut le nom du SP afin que je puisse copier / coller l’appel dans SSMS pour le débogage.


Celles-ci rendent mes fichiers journaux jolis et faciles à générer sans interrompre mon code.

Une paire de méthodes d’extension pour convertir les chaînes de base 36 (!) En entiers:

 public static int ToBase10(this ssortingng base36) { if (ssortingng.IsNullOrEmpty(base36)) return 0; int value = 0; foreach (var c in base36.Trim()) { value = value * 36 + c.ToBase10(); } return value; } public static int ToBase10(this char c) { if (c >= '0' && c <= '9') return c - '0'; c = char.ToUpper(c); if (c >= 'A' && c <= 'Z') return c - 'A' + 10; return 0; } 

(Certains génies ont décidé que le meilleur moyen de stocker des nombres dans la firebase database était de les encoder en chaînes. Les décimales prennent trop de place. L’hex est meilleur, mais n’utilise pas les caractères GZ. )

J’ai écrit une série de méthodes d’extension pour faciliter la manipulation des objects et méthodes ADO.NET:

Créez un DbCommand à partir d’une DbConnection en une seule instruction:

  public static DbCommand CreateCommand(this DbConnection connection, ssortingng commandText) { DbCommand command = connection.CreateCommand(); command.CommandText = commandText; return command; } 

Ajoutez un paramètre à une commande DbCommand:

  public static DbParameter AddParameter(this DbCommand command, ssortingng name, DbType dbType) { DbParameter p = AddParameter(command, name, dbType, 0, ParameterDirection.Input); return p; } public static DbParameter AddParameter(this DbCommand command, ssortingng name, DbType dbType, object value) { DbParameter p = AddParameter(command, name, dbType, 0, ParameterDirection.Input); p.Value = value; return p; } public static DbParameter AddParameter(this DbCommand command, ssortingng name, DbType dbType, int size) { return AddParameter(command, name, dbType, size, ParameterDirection.Input); } public static DbParameter AddParameter(this DbCommand command, ssortingng name, DbType dbType, int size, ParameterDirection direction) { DbParameter parameter = command.CreateParameter(); parameter.ParameterName = name; parameter.DbType = dbType; parameter.Direction = direction; parameter.Size = size; command.Parameters.Add(parameter); return parameter; } 

Accédez aux champs DbDataReader par nom plutôt que par index:

  public static DateTime GetDateTime(this DbDataReader reader, ssortingng name) { int i = reader.GetOrdinal(name); return reader.GetDateTime(i); } public static decimal GetDecimal(this DbDataReader reader, ssortingng name) { int i = reader.GetOrdinal(name); return reader.GetDecimal(i); } public static double GetDouble(this DbDataReader reader, ssortingng name) { int i = reader.GetOrdinal(name); return reader.GetDouble(i); } public static ssortingng GetSsortingng(this DbDataReader reader, ssortingng name) { int i = reader.GetOrdinal(name); return reader.GetSsortingng(i); } ... 

Une autre méthode d’extension (non liée) me permet d’effectuer l’opération DragMove (comme dans WPF) sur les formulaires et les contrôles WinForms, voir ici .

La plupart des exemples de méthodes d’extension que je vois ici vont à l’encontre des meilleures pratiques. Les méthodes d’extension sont puissantes, mais doivent être utilisées avec parcimonie. D’après mon expérience, une classe d’assistance / utilitaire statique avec une syntaxe ancienne serait généralement préférable pour la plupart d’entre eux.

Il y a quelque chose à dire pour les méthodes d’extension pour Enums, car il n’est pas possible pour elles d’avoir des méthodes. Si vous les définissez dans le même espace de noms que votre Enum et dans le même assembly, ils fonctionnent de manière transparente.

Bien que très simple, je trouve que celui-ci est particulièrement utile, car je trouve une page d’un ensemble de résultats complet dix milliards de fois par projet:

 public static class QueryableExtensions { public static IQueryable Page(this IQueryable query, int pageNumber, int pageSize) { int skipCount = (pageNumber-1) * pageSize; query = query.Skip(skipCount); query = query.Take(pageSize); return query; } } 

Souvent, j’ai eu besoin d’afficher une valeur conviviale basée sur une valeur Enum, mais je ne voulais pas passer par l’itinéraire Atsortingbute personnalisé, car il ne semblait pas trop élégant.

Avec cette méthode d’extension pratique:

 public static ssortingng EnumValue(this MyEnum e) { switch (e) { case MyEnum.First: return "First Friendly Value"; case MyEnum.Second: return "Second Friendly Value"; case MyEnum.Third: return "Third Friendly Value"; } return "Horrible Failure!!"; } 

Je peux le faire:

 Console.WriteLine(MyEnum.First.EnumValue()); 

Yay!

Il s’agit d’une méthode d’extension permettant de centraliser les contrôles null avant de déclencher des événements.

 public static class EventExtension { public static void RaiseEvent(this EventHandler handler, object obj, T args) where T : EventArgs { EventHandler theHandler = handler; if (theHandler != null) { theHandler(obj, args); } } } 

Celui-ci est incroyablement simple, mais c’est une vérification que je fais beaucoup alors j’ai fini par en faire une méthode d’extension. Mes méthodes d’extension préférées ont tendance à être les plus simples, les plus simples comme celle-ci, ou comme la méthode d’extension de Taylor L pour déclencher des événements.

 public static bool IsNullOrEmpty(this ICollection e) { return e == null || e.Count == 0; } 

Pour permettre un code combinatoire plus fonctionnel:

  public static Func TryCoalesce(this Func f, R coalesce) { return x => { try { return f(x); } catch { return coalesce; } }; } public static TResult TryCoalesce(this Func f, T p, TResult coalesce) { return f.TryCoalesce(coalesce)(p); } 

Alors je pourrais écrire quelque chose comme ceci:

  public static int ParseInt(this ssortingng str, int coalesce) { return TryCoalesce(int.Parse, str, coalesce); } 

Un autre ensemble que j’utilise assez souvent est la coalescence des méthodes IDictionary:

  public static TValue Get(this IDictionary d, TKey key, Func valueThunk) { TValue v = d.Get(key); if (v == null) { v = valueThunk(); d.Add(key, v); } return v; } public static TValue Get(this IDictionary d, TKey key, TValue coalesce) { return Get(d, key, () => coalesce); } 

Et pour travailler avec des collections en général:

  public static IEnumerable AsCollection(this T item) { yield return item; } 

Ensuite, pour les structures arborescentes:

  public static LinkedList Up(this T node, Func parent) { var list = new LinkedList(); node.Up(parent, n => list.AddFirst(n)); return list; } 

Je peux donc facilement parcourir et utiliser une classe comme:

 class Category { public ssortingng Name { get; set; } public Category Parent { get; set; } } 

Ensuite, pour faciliter la composition des fonctions et une méthode de programmation plus proche de F # en C #:

 public static Func Func(this Func f) { return f; } public static Func Compose(this Func f, Func g) { return x => g(f(x)); } 

Je convertis beaucoup de Java en C #. Beaucoup de méthodes ne varient que dans les majuscules ou les petites différences de syntaxe. Donc, le code Java tel que

 mySsortingng.toLowerCase(); 

ne comstack pas mais en ajoutant une méthode d’extension

 public static void toLowerCase(this ssortingng s) { s.ToLower(); } 

Je peux attraper toutes les méthodes (et je suppose qu’un bon compilateur va l’inclure de toute façon?).

Cela a certainement rendu le travail beaucoup plus facile et plus fiable. (Je remercie @Yuriy – voir la réponse dans: différences entre SsortingngBuilder en Java et C # ) pour la suggestion.

J’aime celui-ci C’est une variante de la méthode Ssortingng.Split qui permet d’utiliser un caractère d’échappement pour supprimer le fractionnement lorsque le caractère divisé est destiné à être dans la chaîne réelle.

Méthode d’extension sur int pour décoder un masque binary spécifiant les jours (le premier jour de la semaine étant le lundi dans ce cas) à une énumération des énumérations DayOfWeek:

 public static IEnumerable Days(this int dayMask) { if ((dayMask & 1) > 0) yield return DayOfWeek.Monday; if ((dayMask & 2) > 0) yield return DayOfWeek.Tuesday; if ((dayMask & 4) > 0) yield return DayOfWeek.Wednesday; if ((dayMask & 8) > 0) yield return DayOfWeek.Thursday; if ((dayMask & 16) > 0) yield return DayOfWeek.Friday; if ((dayMask & 32) > 0) yield return DayOfWeek.Saturday; if ((dayMask & 64) > 0) yield return DayOfWeek.Sunday; } 

Celui-ci crée un tableau avec un seul élément ajouté au tout début:

 public static T[] Prepend(this T[] array, T item) { T[] result = new T[array.Length + 1]; result[0] = item; Array.Copy(array, 0, result, 1, array.Length); return result; } ssortingng[] some = new ssortingng[] { "foo", "bar" }; ... some = some.Prepend("baz"); 

Et celui-ci m’aide quand j’ai besoin de convertir une expression en carré:

 public static double Sq(this double arg) { return arg * arg; } (x - x0).Sq() + (y - y0).Sq() + (z - z0).Sq() 

Here’s another one I wrote:

  public static class SsortingngExtensions { ///  /// Returns a Subset ssortingng starting at the specified start index and ending and the specified end /// index. ///  /// The ssortingng to resortingeve the subset from. /// The specified start index for the subset. /// The specified end index for the subset. /// A Subset ssortingng starting at the specified start index and ending and the specified end /// index. public static ssortingng Subsetssortingng(this ssortingng s, int startIndex, int endIndex) { if (startIndex < 0) throw new ArgumentOutOfRangeException("startIndex", "Must be positive."); if (endIndex < 0) throw new ArgumentOutOfRangeException("endIndex", "Must be positive."); if (startIndex > endIndex) throw new ArgumentOutOfRangeException("endIndex", "Must be >= startIndex."); return s.Subssortingng(startIndex, (endIndex - startIndex)); } ///  /// Finds the specified Start Text and the End Text in this ssortingng instance, and returns a ssortingng /// containing all the text starting from startText, to the begining of endText. (endText is not /// included.) ///  /// The ssortingng to resortingeve the subset from. /// The Start Text to begin the Subset from. /// The End Text to where the Subset goes to. /// Whether or not to ignore case when comparing startText/endText to the ssortingng. /// A ssortingng containing all the text starting from startText, to the begining of endText. public static ssortingng Subsetssortingng(this ssortingng s, ssortingng startText, ssortingng endText, bool ignoreCase) { if (ssortingng.IsNullOrEmpty(startText)) throw new ArgumentNullException("startText", "Must be filled."); if (ssortingng.IsNullOrEmpty(endText)) throw new ArgumentNullException("endText", "Must be filled."); ssortingng temp = s; if (ignoreCase) { temp = s.ToUpperInvariant(); startText = startText.ToUpperInvariant(); endText = endText.ToUpperInvariant(); } int start = temp.IndexOf(startText); int end = temp.IndexOf(endText, start); return Subsetssortingng(s, start, end); } } 

The motivation behind this one was simple. It always bugged me how the built in Subssortingng method took startindex and length as it’s parameters. It’s ALWAYS much more helpful to do startindex and endindex. So, I rolled my own:

Usage:

  ssortingng s = "This is a tester for my cool extension method!!"; s = s.Subsetssortingng("tester", "cool",true); 

The reason I had to use Subsetssortingng was because Subssortingng’s overload already takes two ints. If anyone has a better name, please, let me know!!

cool, also loving Extensions!

here’s a few.

This one will get the last Date of a Month:

  _ Public Function GetLastMonthDay(ByVal Source As DateTime) As DateTime Dim CurrentMonth As Integer = Source.Month Dim MonthCounter As Integer = Source.Month Dim LastDay As DateTime Dim DateCounter As DateTime = Source LastDay = Source Do While MonthCounter = CurrentMonth DateCounter = DateCounter.AddDays(1) MonthCounter = DateCounter.Month If MonthCounter = CurrentMonth Then LastDay = DateCounter End If Loop Return LastDay End Function 

these two make reflection a bit easier:

   _ Public Function GetPropertyValue(Of ValueType)(ByVal Source As Object, ByVal PropertyName As Ssortingng) As ValueType Dim pInfo As System.Reflection.PropertyInfo pInfo = Source.GetType.GetProperty(PropertyName) If pInfo Is Nothing Then Throw New Exception("Property " & PropertyName & " does not exists for object of type " & Source.GetType.Name) Else Return pInfo.GetValue(Source, Nothing) End If End Function  _ Public Function GetPropertyType(ByVal Source As Object, ByVal PropertyName As Ssortingng) As Type Dim pInfo As System.Reflection.PropertyInfo pInfo = Source.GetType.GetProperty(PropertyName) If pInfo Is Nothing Then Throw New Exception("Property " & PropertyName & " does not exists for object of type " & Source.GetType.Name) Else Return pInfo.PropertyType End If End Function 

The extension methods I use the most would have to be the ones in the System.Linq.Enumerable class.

And a good and useful extension to that list you can find in MoreLinq .

There are a couple that I’ve mentioned here that I use:

  • Easier checking on flags enums

    if( enumVar.IsSet( MyEnum.PossibleFlag ) ) //..then

  • Inline checking of nulls

    myObject.IfNotNull( x => x.Property );

few extensions I use mostly. first set is object extensions, really only for converting.

 public static class ObjectExtension { public static T As(this object value) { return (value != null && value is T) ? (T)value : default(T); } public static int AsInt(this ssortingng value) { if (value.HasValue()) { int result; var success = int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result); if (success) { return result; } } return 0; } public static Guid AsGuid(this ssortingng value) { return value.HasValue() ? new Guid(value) : Guid.Empty; } } 

ssortingng extensions

 public static class SsortingngExtension { public static bool HasValue(this ssortingng value) { return ssortingng.IsNullOrEmpty(value) == false; } public static ssortingng Slug(this ssortingng value) { if (value.HasValue()) { var builder = new SsortingngBuilder(); var slug = value.Trim().ToLower(); foreach (var c in slug) { switch (c) { case ' ': builder.Append("-"); break; case '&': builder.Append("and"); break; default: if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') && c != '-') { builder.Append(c); } break; } } return builder.ToString(); } return string.Empty; } public static string Truncate(this string value, int limit) { return (value.Length > limit) ? ssortingng.Concat(value.Subssortingng(0, Math.Min(value.Length, limit)), "...") : value; } } 

and last is some enum extensions

 public static class EnumExtensions { public static bool Has(this Enum source, params T[] values) { var value = Convert.ToInt32(source, CultureInfo.InvariantCulture); foreach (var i in values) { var mask = Convert.ToInt32(i, CultureInfo.InvariantCulture); if ((value & mask) == 0) { return false; } } return true; } public static bool Has(this Enum source, T values) { var value = Convert.ToInt32(source, CultureInfo.InvariantCulture); var mask = Convert.ToInt32(values, CultureInfo.InvariantCulture); return (value & mask) != 0; } public static T Add(this Enum source, T v) { var value = Convert.ToInt32(source, CultureInfo.InvariantCulture); var mask = Convert.ToInt32(v, CultureInfo.InvariantCulture); return Enum.ToObject(typeof(T), value | mask).As(); } public static T Remove(this Enum source, T v) { var value = Convert.ToInt32(source, CultureInfo.InvariantCulture); var mask = Convert.ToInt32(v, CultureInfo.InvariantCulture); return Enum.ToObject(typeof(T), value & ~mask).As(); } public static T AsEnum(this ssortingng value) { try { return Enum.Parse(typeof(T), value, true).As(); } catch { return default(T); } } } 

With regular use of SsortingngBuilder, you may see the need to combine AppendFormat() and AppendLine().

 public static void AppendFormatLine(this SsortingngBuilder sb, ssortingng format, params object[] args) { sb.AppendFormat(format, args); sb.AppendLine(); } 

Also, since I’m converting an application from VB6 to C#, the following are very useful to me:

 public static ssortingng Left(this ssortingng s, int length) { if (s.Length >= length) return s.Subssortingng(0, length); throw new ArgumentException("Length must be less than the length of the ssortingng."); } public static ssortingng Right(this ssortingng s, int length) { if (s.Length >= length) return s.Subssortingng(s.Length - length, length); throw new ArgumentException("Length must be less than the length of the ssortingng."); } 

My favourite from my own personal collection of ssortingng utils is one that will parse a strongly typed value from a ssortingng for any type that has a TryParse method:

 public static class SsortingngUtils { ///  /// This method will parse a value from a ssortingng. /// If the ssortingng is null or not the right format to parse a valid value, /// it will return the default value provided. ///  public static T To(this ssortingng value, T defaultValue) where T: struct { var type = typeof(T); if (value != null) { var parse = type.GetMethod("TryParse", new Type[] { typeof(ssortingng), type.MakeByRefType() }); var parameters = new object[] { value, default(T) }; if((bool)parse.Invoke(null, parameters)) return (T)parameters[1]; } return defaultValue; } ///  /// This method will parse a value from a ssortingng. /// If the ssortingng is null or not the right format to parse a valid value, /// it will return the default value for the type. ///  public static T To(this ssortingng value) where T : struct { return value.To(default(T)); } } 

It’s great for getting strongly typed information from query ssortingngs:

 var value = Request.QuerySsortingng["value"].To(); 

I hate having to do this everywhere:

 DataSet ds = dataLayer.GetSomeData(1, 2, 3); if(ds != null){ if(ds.Tables.Count > 0){ DataTable dt = ds.Tables[0]; foreach(DataRow dr in dt.Rows){ //Do some processing } } } 

Instead I usually use the following Extension Method:

 public static IEnumerable DataRows(this DataSet current){ if(current != null){ if(current.Tables.Count > 0){ DataTable dt = current.Tables[0]; foreach(DataRow dr in dt.Rows){ yield return dr; } } } } 

So the first example then becomes:

 foreach(DataRow row in ds.DataRows()){ //Do some processing } 

Yay, Extension Methods!

Ssortingng.format should not have been static. So I use an extension method called frmt:

  Public Function frmt(ByVal format As Ssortingng, ByVal ParamArray args() As Object) As Ssortingng If format Is Nothing Then Throw New ArgumentNullException("format") Return Ssortingng.Format(format, args) End Function 

When I want to read or write a number to a byte stream without constructing a binary writer (technically you aren’t supposed to modify the raw stream after you’ve wrapped it with a writer):

  Public Function Bytes(ByVal n As ULong, ByVal byteOrder As ByteOrder, Optional ByVal size As Integer = 8) As Byte() Dim data As New List(Of Byte) Do Until data.Count >= size data.Add(CByte(n And CULng(&HFF))) n >>= 8 Loop Select Case byteOrder Case ByteOrder.BigEndian Return data.ToArray.reversed Case ByteOrder.LittleEndian Return data.ToArray Case Else Throw New ArgumentException("Unrecognized byte order.") End Select End Function  Public Function ToULong(ByVal data As IEnumerable(Of Byte), ByVal byteOrder As ByteOrder) As ULong If data Is Nothing Then Throw New ArgumentNullException("data") Dim val As ULong Select Case byteOrder Case ByteOrder.LittleEndian data = data.Reverse Case ByteOrder.BigEndian 'no change required Case Else Throw New ArgumentException("Unrecognized byte order.") End Select For Each b In data val <<= 8 val = val Or b Next b Return val End Function 

This one shifts a sequence so that you get the given item first. I used it for example to take the day of weeks and shift it so that the first day in the sequence is the first day of the week for the current culture.

  ///  /// Shifts a sequence so that the given  becomes the first. /// Uses the specified equality  to find the item. ///  /// Type of elements in . /// Sequence of elements. /// Item which will become the first. /// Used to find the first item. /// A shifted sequence. For example Shift({1,2,3,4,5,6}, 3) would become {3,4,5,6,1,2}.  public static IEnumerable Shift(this IEnumerable source, TSource item, IEqualityComparer comparer) { var queue = new Queue(); bool found = false; foreach (TSource e in source) { if (!found && comparer.Equals(item, e)) found = true; if (found) yield return e; else queue.Enqueue(e); } while (queue.Count > 0) yield return queue.Dequeue(); } ///  /// Shifts a sequence so that the given item becomes the first. /// Uses the default equality comparer to find the item. ///  /// Type of elements in . /// Sequence of elements. /// Element which will become the first. /// A shifted sequence. For example Shift({1,2,3,4,5,6}, 3) would become {3,4,5,6,1,2}.  public static IEnumerable Shift(this IEnumerable source, TSource element) { return Shift(source, element, EqualityComparer.Default); }