¿Cuáles son tus métodos de extensión favoritos para C #? (codeplex.com/extensionoverflow)

Hagamos una lista de respuestas donde publique sus métodos de extensión excelentes y favoritos.

El requisito es que se publique el código completo y un ejemplo y una explicación sobre cómo usarlo.

Basado en el gran interés en este tema, he configurado un proyecto de código abierto llamado extensionoverflow en Codeplex .

Marque sus respuestas con una aceptación para poner el código en el proyecto Codeplex.

Por favor, publique el código fuente completo y no un enlace.

Noticias de Codeplex:

24.08.2010 La página de Codeplex ahora está aquí: http://extensionoverflow.codeplex.com/

11.11.2008 XmlSerialize / XmlDeserialize ahora se implementa y se prueba la unidad .

11.11.2008 Todavía hay espacio para más desarrolladores. 😉 Únete AHORA!

11.11.2008 Third contributer se unió a ExtensionOverflow , bienvenido a BKristensen

11.11.2008 FormatWith ahora se implementa y se prueba la unidad .

09.11.2008 Second contributer se unió a ExtensionOverflow . bienvenido a chakrit

09.11.2008 Necesitamos más desarrolladores. 😉

09.11.2008 ThrowIfArgumentIsNull ahora implementado y probado en Codeplex.

public static bool In(this T source, params T[] list) { if(null==source) throw new ArgumentNullException("source"); return list.Contains(source); } 

Me permite reemplazar:

 if(reallyLongIntegerVariableName == 1 || reallyLongIntegerVariableName == 6 || reallyLongIntegerVariableName == 9 || reallyLongIntegerVariableName == 11) { // do something.... } and if(reallyLongStringVariableName == "string1" || reallyLongStringVariableName == "string2" || reallyLongStringVariableName == "string3") { // do something.... } and if(reallyLongMethodParameterName == SomeEnum.Value1 || reallyLongMethodParameterName == SomeEnum.Value2 || reallyLongMethodParameterName == SomeEnum.Value3 || reallyLongMethodParameterName == SomeEnum.Value4) { // do something.... } 

Con:

 if(reallyLongIntegerVariableName.In(1,6,9,11)) { // do something.... } and if(reallyLongStringVariableName.In("string1","string2","string3")) { // do something.... } and if(reallyLongMethodParameterName.In(SomeEnum.Value1, SomeEnum.Value2, SomeEnum.Value3, SomeEnum.Value4) { // do something.... } 

Tengo varios métodos de extensión en mi proyecto MiscUtil (la fuente completa está disponible allí; no voy a repetirla aquí). Mis favoritos, algunos de los cuales involucran otras clases (como rangos):

Fecha y hora, principalmente para pruebas unitarias. No estoy seguro de que los use en producción 🙂

 var birthday = 19.June(1976); var workingDay = 7.Hours() + 30.Minutes(); 

Rangos y pasos – Gracias masivas a Marc Gravell por sus cosas de operador para hacer esto posible:

 var evenNaturals = 2.To(int.MaxValue).Step(2); var daysSinceBirth = birthday.To(DateTime.Today).Step(1.Days()); 

Comparaciones

 var myComparer = ProjectionComparer.Create(Person p => p.Name); var next = myComparer.ThenBy(p => p.Age); var reversed = myComparer.Reverse(); 

Comprobación de argumentos:

 x.ThrowIfNull("x"); 

LINQ to XML aplicado a tipos anónimos (u otros tipos con propiedades apropiadas):

 // Jon32 new { Name="Jon", Age=32}.ToXElements(); // Name="Jon" Age="32" (as XAttributes, obviously) new { Name="Jon", Age=32}.ToXAttributes() 

Push LINQ: llevaría demasiado tiempo explicar aquí, pero búscalo.

string.Format atajo:

 public static class StringExtensions { // Enable quick and more natural string.Format calls public static string F(this string s, params object[] args) { return string.Format(s, args); } } 

Ejemplo:

 var s = "The co-ordinate is ({0}, {1})".F(point.X, point.Y); 

Para copiar y pegar rápido, vaya aquí .

¿No le parece más natural escribir "some string".F("param") lugar de string.Format("some string", "param") ?

Para obtener un nombre más legible , pruebe una de estas sugerencias:

 s = "Hello {0} world {1}!".Fmt("Stack", "Overflow"); s = "Hello {0} world {1}!".FormatBy("Stack", "Overflow"); s = "Hello {0} world {1}!".FormatWith("Stack", "Overflow"); s = "Hello {0} world {1}!".Display("Stack", "Overflow"); s = "Hello {0} world {1}!".With("Stack", "Overflow"); 

..

¿Son estos algún uso?

 public static bool CoinToss(this Random rng) { return rng.Next(2) == 0; } public static T OneOf(this Random rng, params T[] things) { return things[rng.Next(things.Length)]; } Random rand; bool luckyDay = rand.CoinToss(); string babyName = rand.OneOf("John", "George", "Radio XBR74 ROCKS!"); 
 public static class ComparableExtensions { public static bool Between(this T actual, T lower, T upper) where T : IComparable { return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) < 0; } } 

Ejemplo:

 if (myNumber.Between(3,7)) { // .... } 

El método de extensión:

 public static void AddRange(this ICollection list, params S[] values) where S : T { foreach (S value in values) list.Add(value); } 

El método se aplica a todos los tipos y le permite agregar un rango de elementos a una lista como parámetros.

Ejemplo:

 var list = new List(); list.AddRange(5, 4, 8, 4, 2); 

Por supuesto, ponga esto en el proyecto Codeplex.

Serialización / deserialización de objetos a XML:

 /// Serializes an object of type T in to an xml string /// Any class type /// Object to serialize /// A string that represents Xml, empty otherwise public static string XmlSerialize(this T obj) where T : class, new() { if (obj == null) throw new ArgumentNullException("obj"); var serializer = new XmlSerializer(typeof(T)); using (var writer = new StringWriter()) { serializer.Serialize(writer, obj); return writer.ToString(); } } /// Deserializes an xml string in to an object of Type T /// Any class type /// Xml as string to deserialize from /// A new object of type T is successful, null if failed public static T XmlDeserialize(this string xml) where T : class, new() { if (xml == null) throw new ArgumentNullException("xml"); var serializer = new XmlSerializer(typeof(T)); using (var reader = new StringReader(xml)) { try { return (T)serializer.Deserialize(reader); } catch { return null; } // Could not be deserialized to this type. } } 

ForEach for IEnumerables

 public static class FrameworkExtensions { // a map function public static void ForEach(this IEnumerable @enum, Action mapFunction) { foreach (var item in @enum) mapFunction(item); } } 

Ingenuo ejemplo:

 var buttons = GetListOfButtons() as IEnumerable 

Buen ejemplo:

 // no need to type the same assignment 3 times, just // new[] up an array and use foreach + lambda // everything is properly inferred by csc :-) new { itemA, itemB, itemC } .ForEach(item => { item.Number = 1; item.Str = "Hello World!"; }); 

Nota:

Esto no es como Select porque Select espera que su función devuelva algo como para transformarse en otra lista.

Para cada uno simplemente le permite ejecutar algo para cada uno de los elementos sin ninguna transformación / manipulación de datos.

Hice esto para poder progtwigr en un estilo más funcional y me sorprendió que List tenga un ForEach mientras que IEnumerable no.

Pon esto en el proyecto codeplex

Mis extensiones de conversión que te permiten hacer:

 int i = myString.To(); 

Aquí está, como se publicó en TheSoftwareJedi.com

 public static T To(this IConvertible obj) { return (T)Convert.ChangeType(obj, typeof(T)); } public static T ToOrDefault (this IConvertible obj) { try { return To(obj); } catch { return default(T); } } public static bool ToOrDefault (this IConvertible obj, out T newObj) { try { newObj = To(obj); return true; } catch { newObj = default(T); return false; } } public static T ToOrOther (this IConvertible obj, T other) { try { return Toobj); } catch { return other; } } public static bool ToOrOther (this IConvertible obj, out T newObj, T other) { try { newObj = To(obj); return true; } catch { newObj = other; return false; } } public static T ToOrNull (this IConvertible obj) where T : class { try { return To(obj); } catch { return null; } } public static bool ToOrNull (this IConvertible obj, out T newObj) where T : class { try { newObj = To(obj); return true; } catch { newObj = null; return false; } } 

Puede solicitar el valor predeterminado (llamadas al constructor en blanco o “0” para los números) al fallar, especifique un valor “predeterminado” (lo llamo “otro”), o pida nulo (donde T: clase). También proporcioné modelos de excepción silenciosa y un modelo TryParse típico que devuelve un bool que indica la acción realizada, y un parámetro externo contiene el nuevo valor. Entonces nuestro código puede hacer cosas como esta

 int i = myString.To(); string a = myInt.ToOrDefault(); //note type inference DateTime d = myString.ToOrOther(DateTime.MAX_VALUE); double d; //note type inference bool didItGiveDefault = myString.ToOrDefault(out d); string s = myDateTime.ToOrNull(); 

No pude conseguir que los tipos Nullable se enrollaran en todo el asunto muy limpiamente. Intenté durante unos 20 minutos antes de tirar la toalla.

Tengo un método de extensión para registrar excepciones:

 public static void Log(this Exception obj) { //your logging logic here } 

Y se usa así:

 try { //Your stuff here } catch(Exception ex) { ex.Log(); } 

[lo siento por publicar dos veces; el segundo está mejor diseñado :-)]

 public static class StringExtensions { ///  /// Parses a string into an Enum ///  /// The type of the Enum /// String value to parse /// The Enum corresponding to the stringExtensions public static T EnumParse(this string value) { return StringExtensions.EnumParse(value, false); } public static T EnumParse(this string value, bool ignorecase) { if (value == null) { throw new ArgumentNullException("value"); } value = value.Trim(); if (value.Length == 0) { throw new ArgumentException("Must specify valid information for parsing in the string.", "value"); } Type t = typeof(T); if (!t.IsEnum) { throw new ArgumentException("Type provided must be an Enum.", "T"); } return (T)Enum.Parse(t, value, ignorecase); } } 

Útil para analizar una cadena en un Enum.

 public enum TestEnum { Bar, Test } public class Test { public void Test() { TestEnum foo = "Test".EnumParse(); } } 

El crédito es para Scott Dorman

— Editar para el proyecto Codeplex —

Le pregunté a Scott Dorman si le importaría que publiquemos su código en el proyecto Codeplex. Esta es la respuesta que obtuve de él:

Gracias por el aviso tanto en la publicación SO como en el proyecto CodePlex. He votado a favor su respuesta a la pregunta. Sí, el código es efectivamente de dominio público actualmente bajo CodeProject Open License ( http://www.codeproject.com/info/cpol10.aspx ).

No tengo problemas para incluir esto en el proyecto CodePlex, y si desea agregarme al proyecto (el nombre de usuario es sdorman) agregaré ese método más algunos métodos auxiliares enum adicionales.

Encuentro este bastante útil:

 public static class PaulaBean { private static String paula = "Brillant"; public static String GetPaula(this T obj) { return paula; } } 

Puede usarlo en CodePlex.

DateTimeExtensions

Ejemplos:

 DateTime firstDayOfMonth = DateTime.Now.First(); DateTime lastdayOfMonth = DateTime.Now.Last(); DateTime lastFridayInMonth = DateTime.Now.Last(DayOfWeek.Friday); DateTime nextFriday = DateTime.Now.Next(DayOfWeek.Friday); DateTime lunchTime = DateTime.Now.SetTime(11, 30); DateTime noonOnFriday = DateTime.Now.Next(DayOfWeek.Friday).Noon(); DateTime secondMondayOfMonth = DateTime.Now.First(DayOfWeek.Monday).Next(DayOfWeek.Monday).Midnight(); 

gitorious.org/cadenza es una biblioteca completa de algunos de los métodos de extensión más útiles que he visto.

Aquí hay uno que uso frecuentemente para el formato de presentación.

 public static string ToTitleCase(this string mText) { if (mText == null) return mText; System.Globalization.CultureInfo cultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture; System.Globalization.TextInfo textInfo = cultureInfo.TextInfo; // TextInfo.ToTitleCase only operates on the string if is all lower case, otherwise it returns the string unchanged. return textInfo.ToTitleCase(mText.ToLower()); } 

Aquí hay un to-and-from para números romanos. No se usa a menudo, pero podría ser útil. Uso:

 if ("IV".IsValidRomanNumeral()) { // Do useful stuff with the number 4. } Console.WriteLine("MMMDCCCLXXXVIII".ParseRomanNumeral()); Console.WriteLine(3888.ToRomanNumeralString()); 

La fuente:

  public static class RomanNumeralExtensions { private const int NumberOfRomanNumeralMaps = 13; private static readonly Dictionary romanNumerals = new Dictionary(NumberOfRomanNumeralMaps) { { "M", 1000 }, { "CM", 900 }, { "D", 500 }, { "CD", 400 }, { "C", 100 }, { "XC", 90 }, { "L", 50 }, { "XL", 40 }, { "X", 10 }, { "IX", 9 }, { "V", 5 }, { "IV", 4 }, { "I", 1 } }; private static readonly Regex validRomanNumeral = new Regex( "^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))" + "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$", RegexOptions.Compiled); public static bool IsValidRomanNumeral(this string value) { return validRomanNumeral.IsMatch(value); } public static int ParseRomanNumeral(this string value) { if (value == null) { throw new ArgumentNullException("value"); } value = value.ToUpperInvariant().Trim(); var length = value.Length; if ((length == 0) || !value.IsValidRomanNumeral()) { throw new ArgumentException("Empty or invalid Roman numeral string.", "value"); } var total = 0; var i = length; while (i > 0) { var digit = romanNumerals[value[--i].ToString()]; if (i > 0) { var previousDigit = romanNumerals[value[i - 1].ToString()]; if (previousDigit < digit) { digit -= previousDigit; i--; } } total += digit; } return total; } public static string ToRomanNumeralString(this int value) { const int MinValue = 1; const int MaxValue = 3999; if ((value < MinValue) || (value > MaxValue)) { throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range."); } const int MaxRomanNumeralLength = 15; var sb = new StringBuilder(MaxRomanNumeralLength); foreach (var pair in romanNumerals) { while (value / pair.Value > 0) { sb.Append(pair.Key); value -= pair.Value; } } return sb.ToString(); } } 

Una forma conveniente de lidiar con los tamaños:

 public static class Extensions { public static int K(this int value) { return value * 1024; } public static int M(this int value) { return value * 1024 * 1024; } } public class Program { public void Main() { WSHttpContextBinding serviceMultipleTokenBinding = new WSHttpContextBinding() { MaxBufferPoolSize = 2.M(), // instead of 2097152 MaxReceivedMessageSize = 64.K(), // instead of 65536 }; } } 

Para los controles de Winform:

 ///  /// Returns whether the function is being executed during design time in Visual Studio. ///  public static bool IsDesignTime(this Control control) { if (LicenseManager.UsageMode == LicenseUsageMode.Designtime) { return true; } if (control.Site != null && control.Site.DesignMode) { return true; } var parent = control.Parent; while (parent != null) { if (parent.Site != null && parent.Site.DesignMode) { return true; } parent = parent.Parent; } return false; } ///  /// Sets the DropDownWidth to ensure that no item's text is cut off. ///  public static void SetDropDownWidth(this ComboBox comboBox) { var g = comboBox.CreateGraphics(); var font = comboBox.Font; float maxWidth = 0; foreach (var item in comboBox.Items) { maxWidth = Math.Max(maxWidth, g.MeasureString(item.ToString(), font).Width); } if (comboBox.Items.Count > comboBox.MaxDropDownItems) { maxWidth += SystemInformation.VerticalScrollBarWidth; } comboBox.DropDownWidth = Math.Max(comboBox.Width, Convert.ToInt32(maxWidth)); } 

Uso de IsDesignTime:

 public class SomeForm : Form { public SomeForm() { InitializeComponent(); if (this.IsDesignTime()) { return; } // Do something that makes the visual studio crash or hang if we're in design time, // but any other time executes just fine } } 

Uso de SetDropdownWidth:

 ComboBox cbo = new ComboBox { Width = 50 }; cbo.Items.Add("Short"); cbo.Items.Add("A little longer"); cbo.Items.Add("Holy cow, this is a really, really long item. How in the world will it fit?"); cbo.SetDropDownWidth(); 

Olvidé mencionarlo, siéntete libre de usar estos en Codeplex …

El ThrowIfArgumentIsNull es una buena forma de hacer ese cheque nulo que todos deberíamos hacer.

 public static class Extensions { public static void ThrowIfArgumentIsNull(this T obj, string parameterName) where T : class { if (obj == null) throw new ArgumentNullException(parameterName + " not allowed to be null"); } } 

A continuación se muestra la forma de usarlo y funciona en todas las clases de su espacio de nombres o en cualquier lugar en el que use el espacio de nombres.

 internal class Test { public Test(string input1) { input1.ThrowIfArgumentIsNull("input1"); } } 

Está bien usar este código en el proyecto CodePlex .

Extraño la statement With de Visual Basic cuando me muevo a C #, así que aquí va:

 public static void With(this T obj, Action act) { act(obj); } 

Y aquí está cómo usarlo en C #:

 someVeryVeryLonggggVariableName.With(x => { x.Int = 123; x.Str = "Hello"; x.Str2 = " World!"; }); 

¡Guarda una gran cantidad de tipeo!

Compare esto con:

 someVeryVeryLonggggVariableName.Int = 123; someVeryVeryLonggggVariableName.Str = "Hello"; someVeryVeryLonggggVariableName.Str2 = " World!"; 

poner en proyecto codeplex

Takes a camelCaseWord or PascalCaseWord and “wordifies” it, ie camelCaseWord => camel Case Word

 public static string Wordify( this string camelCaseWord ) { // if the word is all upper, just return it if( !Regex.IsMatch( camelCaseWord, "[az]" ) ) return camelCaseWord; return string.Join( " ", Regex.Split( camelCaseWord, @"(? 

I often use it in conjuction with Capitalize

 public static string Capitalize( this string word ) { return word[0].ToString( ).ToUpper( ) + word.Substring( 1 ); } 

Ejemplo de uso

 SomeEntityObject entity = DataAccessObject.GetSomeEntityObject( id ); List properties = entity.GetType().GetPublicNonCollectionProperties( ); // wordify the property names to act as column headers for an html table or something List columns = properties.Select( p => p.Name.Capitalize( ).Wordify( ) ).ToList( ); 

Free to use in codeplex project

I found this one helpful

 public static IEnumerable EmptyIfNull(this IEnumerable pSeq) { return pSeq ?? Enumerable.Empty(); } 

It removes the null check in the calling code. You could now do

 MyList.EmptyIfNull().Where(....) 

Convert a double to string formatted using the specified culture:

 public static class ExtensionMethods { public static string ToCurrency(this double value, string cultureName) { CultureInfo currentCulture = new CultureInfo(cultureName); return (string.Format(currentCulture, "{0:C}", value)); } } 

Ejemplo:

 double test = 154.20; string testString = test.ToCurrency("en-US"); // $154.20 

Below is an extension method that adapts Rick Strahl’s code (and the comments too) to stop you having to guess or read the byte order mark of a byte array or text file each time you convert it to a string.

The snippet allows you to simply do:

 byte[] buffer = File.ReadAllBytes(@"C:\file.txt"); string content = buffer.GetString(); 

If you find any bugs please add to the comments. Feel free to include it in the Codeplex project.

 public static class Extensions { ///  /// Converts a byte array to a string, using its byte order mark to convert it to the right encoding. /// Original article: http://www.west-wind.com/WebLog/posts/197245.aspx ///  /// An array of bytes to convert /// The byte as a string. public static string GetString(this byte[] buffer) { if (buffer == null || buffer.Length == 0) return ""; // Ansi as default Encoding encoding = Encoding.Default; /* EF BB BF UTF-8 FF FE UTF-16 little endian FE FF UTF-16 big endian FF FE 00 00 UTF-32, little endian 00 00 FE FF UTF-32, big-endian */ if (buffer[0] == 0xef && buffer[1] == 0xbb && buffer[2] == 0xbf) encoding = Encoding.UTF8; else if (buffer[0] == 0xfe && buffer[1] == 0xff) encoding = Encoding.Unicode; else if (buffer[0] == 0xfe && buffer[1] == 0xff) encoding = Encoding.BigEndianUnicode; // utf-16be else if (buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0xfe && buffer[3] == 0xff) encoding = Encoding.UTF32; else if (buffer[0] == 0x2b && buffer[1] == 0x2f && buffer[2] == 0x76) encoding = Encoding.UTF7; using (MemoryStream stream = new MemoryStream()) { stream.Write(buffer, 0, buffer.Length); stream.Seek(0, SeekOrigin.Begin); using (StreamReader reader = new StreamReader(stream, encoding)) { return reader.ReadToEnd(); } } } } 

Here’s one I just created today.

 // requires .NET 4 public static TReturn NullOr(this TIn obj, Func func, TReturn elseValue = default(TReturn)) where TIn : class { return obj != null ? func(obj) : elseValue; } // versions for CLR 2, which doesn't support optional params public static TReturn NullOr(this TIn obj, Func func, TReturn elseValue) where TIn : class { return obj != null ? func(obj) : elseValue; } public static TReturn NullOr(this TIn obj, Func func) where TIn : class { return obj != null ? func(obj) : default(TReturn); } 

Te deja hacer esto:

 var lname = thingy.NullOr(t => t.Name).NullOr(n => n.ToLower()); 

which is more fluent and (IMO) easier to read than this:

 var lname = (thingy != null ? thingy.Name : null) != null ? thingy.Name.ToLower() : null; 

“Please mark your answers with an acceptance to put the code in the Codeplex project.”

¿Por qué? All the Stuff on this site under CC-by-sa-2.5 , so just put your Extension overflow Project under the same license and you can freely use it.

Anyway, here is a String.Reverse function, based on this question .

 ///  /// Reverse a String ///  /// The string to Reverse /// The reversed String public static string Reverse(this string input) { char[] array = input.ToCharArray(); Array.Reverse(array); return new string(array); } 

I got tired of tedious null-checking while pulling values from MySqlDataReader, so:

 public static DateTime? GetNullableDateTime(this MySqlDataReader dr, string fieldName) { DateTime? nullDate = null; return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? nullDate : dr.GetDateTime(fieldName); } public static string GetNullableString(this MySqlDataReader dr, string fieldName) { return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? String.Empty : dr.GetString(fieldName); } public static char? GetNullableChar(this MySqlDataReader dr, string fieldName) { char? nullChar = null; return dr.IsDBNull(dr.GetOrdinal(fieldName)) ? nullChar : dr.GetChar(fieldName); } 

Of course this could be used with any SqlDataReader.


Both hangy and Joe had some good comments on how to do this, and I have since had an opportunity to implement something similar in a different context, so here is another version:

 public static int? GetNullableInt32(this IDataRecord dr, int ordinal) { int? nullInt = null; return dr.IsDBNull(ordinal) ? nullInt : dr.GetInt32(ordinal); } public static int? GetNullableInt32(this IDataRecord dr, string fieldname) { int ordinal = dr.GetOrdinal(fieldname); return dr.GetNullableInt32(ordinal); } public static bool? GetNullableBoolean(this IDataRecord dr, int ordinal) { bool? nullBool = null; return dr.IsDBNull(ordinal) ? nullBool : dr.GetBoolean(ordinal); } public static bool? GetNullableBoolean(this IDataRecord dr, string fieldname) { int ordinal = dr.GetOrdinal(fieldname); return dr.GetNullableBoolean(ordinal); } 

It irritated me that LINQ gives me an OrderBy that takes a class implementing IComparer as an argument, but does not support passing in a simple anonymous comparer function. I rectified that.

This class creates an IComparer from your comparer function…

 ///  /// Creates an  instance for the given /// delegate function. ///  internal class ComparerFactory : IComparer { public static IComparer Create(Func comparison) { return new ComparerFactory(comparison); } private readonly Func _comparison; private ComparerFactory(Func comparison) { _comparison = comparison; } #region IComparer Members public int Compare(T x, T y) { return _comparison(x, y); } #endregion } 

…and these extension methods expose my new OrderBy overloads on enumerables. I doubt this works for LINQ to SQL, but it’s great for LINQ to Objects.

 public static class EnumerableExtensions { ///  /// Sorts the elements of a sequence in ascending order by using a specified comparison delegate. ///  public static IOrderedEnumerable OrderBy(this IEnumerable source, Func keySelector, Func comparison) { var comparer = ComparerFactory.Create(comparison); return source.OrderBy(keySelector, comparer); } ///  /// Sorts the elements of a sequence in descending order by using a specified comparison delegate. ///  public static IOrderedEnumerable OrderByDescending(this IEnumerable source, Func keySelector, Func comparison) { var comparer = ComparerFactory.Create(comparison); return source.OrderByDescending(keySelector, comparer); } } 

You’re welcome to put this on codeplex if you like.

This one is for MVC it adds the ability to generate a tag to the Html variable that is available in every ViewPage . Hopefully it will be of use to others trying to develop similar extensions.

Utilizar:

 <%= Html.Label("LabelId", "ForId", "Text")%> 

Salida:

  

Código:

 public static class HtmlHelperExtensions { public static string Label(this HtmlHelper Html, string @for, string text) { return Html.Label(null, @for, text); } public static string Label(this HtmlHelper Html, string @for, string text, object htmlAttributes) { return Html.Label(null, @for, text, htmlAttributes); } public static string Label(this HtmlHelper Html, string @for, string text, IDictionary htmlAttributes) { return Html.Label(null, @for, text, htmlAttributes); } public static string Label(this HtmlHelper Html, string id, string @for, string text) { return Html.Label(id, @for, text, null); } public static string Label(this HtmlHelper Html, string id, string @for, string text, object htmlAttributes) { return Html.Label(id, @for, text, new RouteValueDictionary(htmlAttributes)); } public static string Label(this HtmlHelper Html, string id, string @for, string text, IDictionary htmlAttributes) { TagBuilder tag = new TagBuilder("label"); tag.MergeAttributes(htmlAttributes); if (!string.IsNullOrEmpty(id)) tag.MergeAttribute("id", Html.AttributeEncode(id)); tag.MergeAttribute("for", Html.AttributeEncode(@for)); tag.SetInnerText(Html.Encode(text)); return tag.ToString(TagRenderMode.Normal); } } 

Turn this:

 DbCommand command = connection.CreateCommand(); command.CommandText = "SELECT @param"; DbParameter param = command.CreateParameter(); param.ParameterName = "@param"; param.Value = "Hello World"; command.Parameters.Add(param); 

… into this:

 DbCommand command = connection.CreateCommand("SELECT {0}", "Hello World"); 

… using this extension method:

 using System; using System.Data.Common; using System.Globalization; using System.Reflection; namespace DbExtensions { public static class Db { static readonly Func getDbProviderFactory; static readonly Func getParameterName; static readonly Func getParameterPlaceholder; static Db() { getDbProviderFactory = (Func)Delegate.CreateDelegate(typeof(Func), typeof(DbConnection).GetProperty("DbProviderFactory", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(true)); getParameterName = (Func)Delegate.CreateDelegate(typeof(Func), typeof(DbCommandBuilder).GetMethod("GetParameterName", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null)); getParameterPlaceholder = (Func)Delegate.CreateDelegate(typeof(Func), typeof(DbCommandBuilder).GetMethod("GetParameterPlaceholder", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null)); } public static DbProviderFactory GetProviderFactory(this DbConnection connection) { return getDbProviderFactory(connection); } public static DbCommand CreateCommand(this DbConnection connection, string commandText, params object[] parameters) { if (connection == null) throw new ArgumentNullException("connection"); return CreateCommandImpl(GetProviderFactory(connection).CreateCommandBuilder(), connection.CreateCommand(), commandText, parameters); } private static DbCommand CreateCommandImpl(DbCommandBuilder commandBuilder, DbCommand command, string commandText, params object[] parameters) { if (commandBuilder == null) throw new ArgumentNullException("commandBuilder"); if (command == null) throw new ArgumentNullException("command"); if (commandText == null) throw new ArgumentNullException("commandText"); if (parameters == null || parameters.Length == 0) { command.CommandText = commandText; return command; } object[] paramPlaceholders = new object[parameters.Length]; for (int i = 0; i < paramPlaceholders.Length; i++) { DbParameter dbParam = command.CreateParameter(); dbParam.ParameterName = getParameterName(commandBuilder, i); dbParam.Value = parameters[i] ?? DBNull.Value; command.Parameters.Add(dbParam); paramPlaceholders[i] = getParameterPlaceholder(commandBuilder, i); } command.CommandText = String.Format(CultureInfo.InvariantCulture, commandText, paramPlaceholders); return command; } } } 

More ADO.NET extension methods: DbExtensions