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

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

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


当前回答

For adding multiple elements to a collection that doesn't have AddRange, e.g., collection.Add(item1, item2, itemN); static void Add<T>(this ICollection<T> coll, params T[] items) { foreach (var item in items) coll.Add(item); } The following is like string.Format() but with custom string representation of arguments, e.g., "{0} {1} {2}".Format<Custom>(c=>c.Name,"string",new object(),new Custom()) results in "string {System.Object} Custom1Name" static string Format<T>( this string format , Func<T,object> select , params object[] args) { for(int i=0; i < args.Length; ++i) { var x = args[i] as T; if (x != null) args[i] = select(x); } return string.Format(format, args); }

其他回答

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

允许我替换:

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....
}

:

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....
}

使用反射查找TryParse方法并在字符串目标上调用它。可选参数指定转换失败时应返回的内容。我发现这个方法在大多数时候都很有用。很清楚皈依者。ChangeType选项,但我发现这更有用的什么与默认结果方便和什么。请注意,找到的方法保存在字典中,尽管我确实怀疑装箱最终会降低一点速度。

这种方法是我最喜欢的,因为它合理地使用了许多语言特性。

private static readonly Dictionary<Type, MethodInfo> Parsers = new Dictionary<Type, MethodInfo>();

public static T Parse<T>(this string value, T defaultValue = default(T))
{
    if (string.IsNullOrEmpty(value)) return defaultValue;

    if (!Parsers.ContainsKey(typeof(T)))
        Parsers[typeof (T)] = typeof (T).GetMethods(BindingFlags.Public | BindingFlags.Static)
            .Where(mi => mi.Name == "TryParse")
            .Single(mi =>
                        {
                            var parameters = mi.GetParameters();
                            if (parameters.Length != 2) return false;
                            return parameters[0].ParameterType == typeof (string) &&
                                   parameters[1].ParameterType == typeof (T).MakeByRefType();
                        });

    var @params = new object[] {value, default(T)};
    return (bool) Parsers[typeof (T)].Invoke(null, @params) ?
        (T) @params[1] : defaultValue;
}

用法:

var hundredTwentyThree = "123".Parse(0);
var badnumber = "test".Parse(-1);
var date = "01/01/01".Parse<DateTime>();

字符串。As<T>,可用于将字符串值转换为某种类型(主要用于支持IConvertable的原语和类型)。工作伟大的空类型,甚至枚举!

public static partial class StringExtensions
{
    /// <summary>
    /// Converts the string to the specified type, using the default value configured for the type.
    /// </summary>
    /// <typeparam name="T">Type the string will be converted to. The type must implement IConvertable.</typeparam>
    /// <param name="original">The original string.</param>
    /// <returns>The converted value.</returns>
    public static T As<T>(this String original)
    {
        return As(original, CultureInfo.CurrentCulture,
                  default(T));
    }

    /// <summary>
    /// Converts the string to the specified type, using the default value configured for the type.
    /// </summary>
    /// <typeparam name="T">Type the string will be converted to.</typeparam>
    /// <param name="original">The original string.</param>
    /// <param name="defaultValue">The default value to use in case the original string is null or empty, or can't be converted.</param>
    /// <returns>The converted value.</returns>
    public static T As<T>(this String original, T defaultValue)
    {
        return As(original, CultureInfo.CurrentCulture, defaultValue);
    }

    /// <summary>
    /// Converts the string to the specified type, using the default value configured for the type.
    /// </summary>
    /// <typeparam name="T">Type the string will be converted to.</typeparam>
    /// <param name="original">The original string.</param>
    /// <param name="provider">Format provider used during the type conversion.</param>
    /// <returns>The converted value.</returns>
    public static T As<T>(this String original, IFormatProvider provider)
    {
        return As(original, provider, default(T));
    }

    /// <summary>
    /// Converts the string to the specified type.
    /// </summary>
    /// <typeparam name="T">Type the string will be converted to.</typeparam>
    /// <param name="original">The original string.</param>
    /// <param name="provider">Format provider used during the type conversion.</param>
    /// <param name="defaultValue">The default value to use in case the original string is null or empty, or can't be converted.</param>
    /// <returns>The converted value.</returns>
    /// <remarks>
    /// If an error occurs while converting the specified value to the requested type, the exception is caught and the default is returned. It is strongly recommended you
    /// do NOT use this method if it is important that conversion failures are not swallowed up.
    ///
    /// This method is intended to be used to convert string values to primatives, not for parsing, converting, or deserializing complex types.
    /// </remarks>
    public static T As<T>(this String original, IFormatProvider provider,
                          T defaultValue)
    {
        T result;
        Type type = typeof (T);

        if (String.IsNullOrEmpty(original)) result = defaultValue;
        else
        {
            // need to get the underlying type if T is Nullable<>.

            if (type.IsNullableType())
            {
                type = Nullable.GetUnderlyingType(type);
            }

            try
            {
                // ChangeType doesn't work properly on Enums
                result = type.IsEnum
                             ? (T) Enum.Parse(type, original, true)
                             : (T) Convert.ChangeType(original, type, provider);
            }
            catch // HACK: what can we do to minimize or avoid raising exceptions as part of normal operation? custom string parsing (regex?) for well-known types? it would be best to know if you can convert to the desired type before you attempt to do so.
            {
                result = defaultValue;
            }
        }

        return result;
    }
}

这依赖于Type的另一个简单扩展:

/// <summary>
/// Extension methods for <see cref="Type"/>.
/// </summary>
public static class TypeExtensions
{
    /// <summary>
    /// Returns whether or not the specified type is <see cref="Nullable{T}"/>.
    /// </summary>
    /// <param name="type">A <see cref="Type"/>.</param>
    /// <returns>True if the specified type is <see cref="Nullable{T}"/>; otherwise, false.</returns>
    /// <remarks>Use <see cref="Nullable.GetUnderlyingType"/> to access the underlying type.</remarks>
    public static bool IsNullableType(this Type type)
    {
        if (type == null) throw new ArgumentNullException("type");

        return type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof (Nullable<>));
    }
}

用法:

var someInt = "1".As<int>();
var someIntDefault = "bad value".As(1); // "bad value" won't convert, so the default value 1 is returned.
var someEnum = "Sunday".As<DayOfWeek>();
someEnum = "0".As<DayOfWeek>(); // returns Sunday
var someNullableEnum = "".As<DayOfWeek?>(null); // returns a null value since "" can't be converted

这些有用吗?

public static bool CoinToss(this Random rng)
{
    return rng.Next(2) == 0;
}

public static T OneOf<T>(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!");

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;
}