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

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

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


当前回答

这是另一个控制扩展,我一直在使用,虽然我不知道它是否张贴在这里之前。

public static class ControlExtensions
{
    public static void DoubleBuffer(this Control control) 
    {
        // http://stackoverflow.com/questions/76993/how-to-double-buffer-net-controls-on-a-form/77233#77233
        // Taxes: Remote Desktop Connection and painting: http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx

        if (System.Windows.Forms.SystemInformation.TerminalServerSession) return;
        System.Reflection.PropertyInfo dbProp = typeof(System.Windows.Forms.Control).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
        dbProp.SetValue(control, true, null);
    }
}

用法:

this.someControl.DoubleBuffer();

其他回答

IEnumerable < >洗牌

我用Fisher-Yates算法实现了一个shuffle函数。

通过使用yield return和将代码分解为两个函数,它实现了适当的参数验证和延迟执行。(谢谢丹,在我的第一个版本中指出了这个缺陷)

static public IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
{
    if (source == null) throw new ArgumentNullException("source");

    return ShuffleIterator(source);
}

static private IEnumerable<T> ShuffleIterator<T>(this IEnumerable<T> source)
{
    T[] array = source.ToArray();
    Random rnd = new Random();          
    for (int n = array.Length; n > 1;)
    {
        int k = rnd.Next(n--); // 0 <= k < n

        //Swap items
        if (n != k)
        {
            T tmp = array[k];
            array[k] = array[n];
            array[n] = tmp;
        }
    }

    foreach (var item in array) yield return item;
}

您可以从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);
    }
}

通配符字符串比较:

public static bool MatchesWildcard(this string text, string pattern)
{
    int it = 0;
    while (text.CharAt(it) != 0 &&
           pattern.CharAt(it) != '*')
    {
        if (pattern.CharAt(it) != text.CharAt(it) && pattern.CharAt(it) != '?')
            return false;
        it++;
    }

    int cp = 0;
    int mp = 0;
    int ip = it;

    while (text.CharAt(it) != 0)
    {
        if (pattern.CharAt(ip) == '*')
        {
            if (pattern.CharAt(++ip) == 0)
                return true;
            mp = ip;
            cp = it + 1;
        }
        else if (pattern.CharAt(ip) == text.CharAt(it) || pattern.CharAt(ip) == '?')
        {
            ip++;
            it++;
        }
        else
        {
            ip = mp;
            it = cp++;
        }
    }

    while (pattern.CharAt(ip) == '*')
    {
        ip++;
    }
    return pattern.CharAt(ip) == 0;
}

public static char CharAt(this string s, int index)
{
    if (index < s.Length)
        return s[index];
    return '\0';
}

它直接翻译了本文中的C代码,因此CharAt方法将字符串的末尾返回0

if (fileName.MatchesWildcard("*.cs"))
{
    Console.WriteLine("{0} is a C# source file", fileName);
}

如果您使用财政年度,则有两个有用的扩展

/// <summary>
/// Returns the fiscal year for the passed in date
/// </summary>
/// <param name="value">the date</param>
/// <returns>the fiscal year</returns>
public static int FiscalYear(this DateTime value)
{
  int ret = value.Year;
  if (value.Month >= 7) ret++;
  return ret;
}

/// <summary>
/// Returns the fiscal year for the passed in date
/// </summary>
/// <param name="value">the date</param>
/// <returns>the fiscal year</returns>
public static string FiscalYearString(this DateTime value)
{
  int fy = FiscalYear(value);
  return "{0}/{1}".Format(fy - 1, fy);
}

我最喜欢的是字符串上的IsLike()扩展。IsLike()匹配VB的Like操作符,当你不想写一个完整的正则表达式来解决你的问题时,它很方便。用法是这样的:

"abc".IsLike("a*"); // true
"Abc".IsLike("[A-Z][a-z][a-z]"); // true
"abc123".IsLike("*###"); // true
"hat".IsLike("?at"); // true
"joe".IsLike("[!aeiou]*"); // true

"joe".IsLike("?at"); // false
"joe".IsLike("[A-Z][a-z][a-z]"); // false

下面是代码

public static class StringEntentions {
    /// <summary>
    /// Indicates whether the current string matches the supplied wildcard pattern.  Behaves the same
    /// as VB's "Like" Operator.
    /// </summary>
    /// <param name="s">The string instance where the extension method is called</param>
    /// <param name="wildcardPattern">The wildcard pattern to match.  Syntax matches VB's Like operator.</param>
    /// <returns>true if the string matches the supplied pattern, false otherwise.</returns>
    /// <remarks>See http://msdn.microsoft.com/en-us/library/swf8kaxw(v=VS.100).aspx</remarks>
    public static bool IsLike(this string s, string wildcardPattern) {
        if (s == null || String.IsNullOrEmpty(wildcardPattern)) return false;
        // turn into regex pattern, and match the whole string with ^$
        var regexPattern = "^" + Regex.Escape(wildcardPattern) + "$";

        // add support for ?, #, *, [], and [!]
        regexPattern = regexPattern.Replace(@"\[!", "[^")
                                   .Replace(@"\[", "[")
                                   .Replace(@"\]", "]")
                                   .Replace(@"\?", ".")
                                   .Replace(@"\*", ".*")
                                   .Replace(@"\#", @"\d");

        var result = false;
        try {
            result = Regex.IsMatch(s, regexPattern);
        }
        catch (ArgumentException ex) {
            throw new ArgumentException(String.Format("Invalid pattern: {0}", wildcardPattern), ex);
        }
        return result;
    }
}