让我们把你的优秀和最喜欢的扩展方法列一个列表。

要求是必须发布完整的代码,以及如何使用它的示例和解释。

基于对这个主题的高度兴趣,我在Codeplex上建立了一个名为extensionoverflow的开源项目。

请将您的回答标记为接受,以便将代码放入Codeplex项目。

请张贴完整的源代码,而不是一个链接。

Codeplex上新闻:

24.08.2010 Codeplex页面现在在这里:http://extensionoverflow.codeplex.com/

11.11.2008 XmlSerialize / XmlDeserialize现在是实现和单元测试。

11.11.2008仍有发展空间。;-)现在就加入!

11.11.2008第三位贡献者加入了ExtensionOverflow,欢迎加入BKristensen

11.11.2008 FormatWith现在是实现和单元测试。

09.11.2008第二个贡献者加入ExtensionOverflow。欢迎来到chakrit。

我们需要更多的开发人员。: -)

09.11.2008 ThrowIfArgumentIsNull现已在Codeplex上实现和单元测试。


当前回答

为什么不呢!这是一个扩展到IList(不能是IEnumerable,因为我使用列表特定的功能)插入排序。

internal static class SortingHelpers
{
    /// <summary>
    /// Performs an insertion sort on this list.
    /// </summary>
    /// <typeparam name="T">The type of the list supplied.</typeparam>
    /// <param name="list">the list to sort.</param>
    /// <param name="comparison">the method for comparison of two elements.</param>
    /// <returns></returns>
    public static void InsertionSort<T>(this IList<T> list, Comparison<T> comparison)
    {
        for (int i = 2; i < list.Count; i++)
        {
            for (int j = i; j > 1 && comparison(list[j], list[j - 1]) < 0; j--)
            {
                T tempItem = list[j];
                list.RemoveAt(j);
                list.Insert(j - 1, tempItem);
            }
        }
    }
}

一个例子:

List<int> list1 = { 3, 5, 1, 2, 9, 4, 6 };
list1.InsertionSort((a,b) => a - b);
//list is now in order of 1,2,3,4,5,6,9

其他回答

这个很有用:

    public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult>(this IEnumerable<TFirst> first, IEnumerable<TSecond> second, Func<TFirst, TSecond, TResult> selector)
    {
        if (first == null)
            throw new ArgumentNullException("first");
        if (second == null)
            throw new ArgumentNullException("second");
        if (selector == null)
            throw new ArgumentNullException("selector");

        using (var enum1 = first.GetEnumerator())
        using (var enum2 = second.GetEnumerator())
        {
            while (enum1.MoveNext() && enum2.MoveNext())
            {
                yield return selector(enum1.Current, enum2.Current);
            }
        }
    }

它在。net 4.0中被添加到Enumerable类中,但是在3.5中使用它很方便。

例子:

var names = new[] { "Joe", "Jane", "Jack", "John" };
var ages = new[] { 42, 22, 18, 33 };

var persons = names.Zip(ages, (n, a) => new { Name = n, Age = a });

foreach (var p in persons)
{
    Console.WriteLine("{0} is {1} years old", p.Name, p.Age);
}

把这个:

DbCommand command = connection.CreateCommand();
command.CommandText = "SELECT @param";

DbParameter param = command.CreateParameter();
param.ParameterName = "@param";
param.Value = "Hello World";

command.Parameters.Add(param);

... 到这个:

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

... 使用这个扩展方法:

using System;
using System.Data.Common;
using System.Globalization;
using System.Reflection;

namespace DbExtensions {

   public static class Db {

      static readonly Func<DbConnection, DbProviderFactory> getDbProviderFactory;
      static readonly Func<DbCommandBuilder, int, string> getParameterName;
      static readonly Func<DbCommandBuilder, int, string> getParameterPlaceholder;

      static Db() {

         getDbProviderFactory = (Func<DbConnection, DbProviderFactory>)Delegate.CreateDelegate(typeof(Func<DbConnection, DbProviderFactory>), typeof(DbConnection).GetProperty("DbProviderFactory", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(true));
         getParameterName = (Func<DbCommandBuilder, int, string>)Delegate.CreateDelegate(typeof(Func<DbCommandBuilder, int, string>), typeof(DbCommandBuilder).GetMethod("GetParameterName", BindingFlags.Instance | BindingFlags.NonPublic, Type.DefaultBinder, new Type[] { typeof(Int32) }, null));
         getParameterPlaceholder = (Func<DbCommandBuilder, int, string>)Delegate.CreateDelegate(typeof(Func<DbCommandBuilder, int, string>), 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;
      }
   }
}

更多的麻烦。NET扩展方法:DbExtensions

您可能已经知道扩展方法的一个有趣用法是作为一种mixin。一些扩展方法,比如XmlSerializable,几乎污染了所有类;这对大多数人来说没有意义,比如Thread和SqlConnection。

一些功能应该显式地混合到希望拥有它的类中。我对这种类型提出了一种新的表示法,以M为前缀。

XmlSerializable是这样的:

public interface MXmlSerializable { }
public static class XmlSerializable {
  public static string ToXml(this MXmlSerializable self) {
    if (self == null) throw new ArgumentNullException();
    var serializer = new XmlSerializer(self.GetType());
    using (var writer = new StringWriter()) {
      serializer.Serialize(writer, self);
      return writer.GetStringBuilder().ToString();
    }
  }
  public static T FromXml<T>(string xml) where T : MXmlSerializable {
    var serializer = new XmlSerializer(typeof(T));
    return (T)serializer.Deserialize(new StringReader(xml));
  }
}

然后一个类将其混合:

public class Customer : MXmlSerializable {
  public string Name { get; set; }
  public bool Preferred { get; set; }
}

用法很简单:

var customer = new Customer { 
  Name = "Guybrush Threepwood", 
  Preferred = true };
var xml = customer.ToXml();

如果您喜欢这个想法,您可以在项目中为有用的mixin创建一个新的名称空间。你怎么看?

哦,顺便说一下,我认为大多数扩展方法都应该显式地测试null。

public static class DictionaryExtensions
{
    public static Nullable<TValue> GetValueOrNull<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
        where TValue : struct
    {
        TValue result;
        if (dictionary.TryGetValue(key, out result))
            return result;
        else
            return null;
    }
}

免费使用,只需在代码中提到我的名字(Janko Röbisch)。

ASP。NET中,我使用这些扩展httpessionstate来加载会话中的对象。 它允许您以干净的方式加载会话对象,如果它们不存在,则将创建和初始化它们。 我使用两个扩展方法,如下所示:

private bool CreateMode;
private MyClass SomeClass;

protected override void OnInit (EventArgs e)
{
    CreateMode = Session.GetSessionValue<bool> ("someKey1", () => true);
    SomeClass = Session.GetSessionClass<MyClass> ("someKey2", () => new MyClass () 
    { 
       MyProperty = 123 
    });
}

下面是扩展类:

public static class SessionExtensions    
{
    public delegate object UponCreate ();
    public static T GetSessionClass<T> (this HttpSessionState session, 
       string key, UponCreate uponCreate) where T : class
    {
        if (null == session[key])
        {
            var item = uponCreate () as T;
            session[key] = item;
            return item;
        }
        return session[key] as T;
    }
    public static T GetSessionValue<T> (this HttpSessionState session, 
       string key, UponCreate uponCreate) where T : struct
    {
        if (null == session[key])
        {
            var item = uponCreate();
            session[key] = item;
            return (T)item;
        }
        return (T)session[key];
    }
}