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

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

基于对这个主题的高度兴趣,我在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上实现和单元测试。


当前回答

我创建了一个漂亮的Each扩展,具有与jQuery的Each函数相同的行为。

它允许如下所示,你可以获得当前值的索引,并通过返回false跳出循环:

new[] { "first", "second", "third" }.Each((value, index) =>
{
    if (value.Contains("d"))
        return false;
    Console.Write(value);
    return true;
});

下面是代码

/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion.  A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value in the sequence. 
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Action<T> action)
{
    return source.Each((value, index) =>
    {
        action(value);
        return true;
    });
}


/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion.  A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value and its index in the sequence.  
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Action<T, int> action)
{
    return source.Each((value, index) =>
    {
        action(value, index);
        return true;
    });
}

/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion.  A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value in the sequence.  Returns a value indicating whether the iteration should continue.  So return false if you don't want to iterate anymore.</param>
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Func<T, bool> action)
{
    return source.Each((value, index) =>
    {
        return action(value);
    });
}

/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion.  A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value and its index in the sequence.  Returns a value indicating whether the iteration should continue.  So return false if you don't want to iterate anymore.</param>
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Func<T, int, bool> action)
{
    if (source == null)
        return source;

    int index = 0;
    foreach (var sourceItem in source)
    {
        if (!action(sourceItem, index))
            break;
        index++;
    }
    return source;
}

其他回答

简单但比“可枚举”更好。范围”,恕我直言:

/// <summary>
/// Replace "Enumerable.Range(n)" with "n.Range()":
/// </summary>
/// <param name="n">iterations</param>
/// <returns>0..n-1</returns>
public static IEnumerable<int> Range(this int n)
{
    for (int i = 0; i < n; i++)
        yield return i;
}

这是我今天刚创建的一个。

// requires .NET 4

public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> 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<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
        TReturn elseValue) where TIn : class
    { return obj != null ? func(obj) : elseValue; }
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func)
        where TIn : class
    { return obj != null ? func(obj) : default(TReturn); }

它让你这样做:

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

哪个比这个更流畅,(依我看)更容易阅读:

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

您可以从Random类中获得许多功能。

下面是我经常使用的一些扩展方法。有了这些,除了Next和NextDouble, Random类还提供了NextBool, NextChar, NextDateTime, NextTimeSpan, NextDouble(接受minValue和maxValue参数),以及我个人最喜欢的NextString。还有更多(NextByte, NextShort, NextLong等);但这些主要是为了完整性,并不经常使用。所以我没有在这里包含它们(这段代码已经足够长了!)。

// todo: implement additional CharType values (e.g., AsciiAny)
public enum CharType {
    AlphabeticLower,
    AlphabeticUpper,
    AlphabeticAny,
    AlphanumericLower,
    AlphanumericUpper,
    AlphanumericAny,
    Numeric
}

public static class RandomExtensions {
    // 10 digits vs. 52 alphabetic characters (upper & lower);
    // probability of being numeric: 10 / 62 = 0.1612903225806452
    private const double AlphanumericProbabilityNumericAny = 10.0 / 62.0;

    // 10 digits vs. 26 alphabetic characters (upper OR lower);
    // probability of being numeric: 10 / 36 = 0.2777777777777778
    private const double AlphanumericProbabilityNumericCased = 10.0 / 36.0;

    public static bool NextBool(this Random random, double probability) {
        return random.NextDouble() <= probability;
    }

    public static bool NextBool(this Random random) {
        return random.NextDouble() <= 0.5;
    }

    public static char NextChar(this Random random, CharType mode) {
        switch (mode) {
            case CharType.AlphabeticAny:
                return random.NextAlphabeticChar();
            case CharType.AlphabeticLower:
                return random.NextAlphabeticChar(false);
            case CharType.AlphabeticUpper:
                return random.NextAlphabeticChar(true);
            case CharType.AlphanumericAny:
                return random.NextAlphanumericChar();
            case CharType.AlphanumericLower:
                return random.NextAlphanumericChar(false);
            case CharType.AlphanumericUpper:
                return random.NextAlphanumericChar(true);
            case CharType.Numeric:
                return random.NextNumericChar();
            default:
                return random.NextAlphanumericChar();
        }
    }

    public static char NextChar(this Random random) {
        return random.NextChar(CharType.AlphanumericAny);
    }

    private static char NextAlphanumericChar(this Random random, bool uppercase) {
        bool numeric = random.NextBool(AlphanumericProbabilityNumericCased);

        if (numeric)
            return random.NextNumericChar();
        else
            return random.NextAlphabeticChar(uppercase);
    }

    private static char NextAlphanumericChar(this Random random) {
        bool numeric = random.NextBool(AlphanumericProbabilityNumericAny);

        if (numeric)
            return random.NextNumericChar();
        else
            return random.NextAlphabeticChar(random.NextBool());
    }

    private static char NextAlphabeticChar(this Random random, bool uppercase) {
        if (uppercase)
            return (char)random.Next(65, 91);
        else
            return (char)random.Next(97, 123);
    }

    private static char NextAlphabeticChar(this Random random) {
        return random.NextAlphabeticChar(random.NextBool());
    }

    private static char NextNumericChar(this Random random) {
        return (char)random.Next(48, 58);
    }

    public static DateTime NextDateTime(this Random random, DateTime minValue, DateTime maxValue) {
        return DateTime.FromOADate(
            random.NextDouble(minValue.ToOADate(), maxValue.ToOADate())
        );
    }

    public static DateTime NextDateTime(this Random random) {
        return random.NextDateTime(DateTime.MinValue, DateTime.MaxValue);
    }

    public static double NextDouble(this Random random, double minValue, double maxValue) {
        if (maxValue < minValue)
            throw new ArgumentException("Minimum value must be less than maximum value.");

        double difference = maxValue - minValue;
        if (!double.IsInfinity(difference))
            return minValue + (random.NextDouble() * difference);

        else {
            // to avoid evaluating to Double.Infinity, we split the range into two halves:
            double halfDifference = (maxValue * 0.5) - (minValue * 0.5);

            // 50/50 chance of returning a value from the first or second half of the range
            if (random.NextBool())
                return minValue + (random.NextDouble() * halfDifference);
            else
                return (minValue + halfDifference) + (random.NextDouble() * halfDifference);
        }
    }

    public static string NextString(this Random random, int numChars, CharType mode) {
        char[] chars = new char[numChars];

        for (int i = 0; i < numChars; ++i)
            chars[i] = random.NextChar(mode);

        return new string(chars);
    }

    public static string NextString(this Random random, int numChars) {
        return random.NextString(numChars, CharType.AlphanumericAny);
    }

    public static TimeSpan NextTimeSpan(this Random random, TimeSpan minValue, TimeSpan maxValue) {
        return TimeSpan.FromMilliseconds(
            random.NextDouble(minValue.TotalMilliseconds, maxValue.TotalMilliseconds)
        );
    }

    public static TimeSpan NextTimeSpan(this Random random) {
        return random.NextTimeSpan(TimeSpan.MinValue, TimeSpan.MaxValue);
    }
}

把这个:

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

每n个字符换行一个字符串。

public static string WrapAt(this string str, int WrapPos)
{
    if (string.IsNullOrEmpty(str))
        throw new ArgumentNullException("str", "Cannot wrap a null string");
    str = str.Replace("\r", "").Replace("\n", "");

    if (str.Length <= WrapPos)
        return str;

    for (int i = str.Length; i >= 0; i--)
        if (i % WrapPos == 0 && i > 0 && i != str.Length)
            str = str.Insert(i, "\r\n");
    return str;
}