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

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

基于对这个主题的高度兴趣,我在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 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....
}

其他回答

有时使用自定义分隔符在列表中选中的元素上写出字符串是很方便的。

例如,如果你有一个List<Person>并且想要用逗号分隔姓氏,你可以这样做。

string result = string.Empty;
foreach (var person in personList) {
   result += person.LastName + ", ";
}
result = result.Substring(0, result.Length - 2);
return result;

或者你可以使用这个方便的扩展方法

public static string Join<T>(this IEnumerable<T> collection, Func<T, string> func, string separator)
{
  return String.Join(separator, collection.Select(func).ToArray());
}

像这样使用它

personList.Join(x => x.LastName, ", ");

这将产生相同的结果,在本例中是由逗号分隔的姓氏列表。

一些我最好的方法扩展(我有很多!):

public static T ToEnum<T>(this string str) where T : struct
{
    return (T)Enum.Parse(typeof(T), str);
}

//DayOfWeek sunday =  "Sunday".ToEnum<DayOfWeek>();

public static string ToString<T>(this IEnumerable<T> collection, string separator)
{
    return ToString(collection, t => t.ToString(), separator);
}

public static string ToString<T>(this IEnumerable<T> collection, Func<T, string> stringElement, string separator)
{
    StringBuilder sb = new StringBuilder();
    foreach (var item in collection)
    {
        sb.Append(stringElement(item));
        sb.Append(separator);
    }
    return sb.ToString(0, Math.Max(0, sb.Length - separator.Length));  // quita el ultimo separador
}

//new []{1,2,3}.ToString(i=>i*2, ", ")  --> "2, 4, 6"

此外,下一个意味着能够在几乎任何情况下继续在同一行中,而不是声明新变量然后删除状态:

public static R Map<T, R>(this T t, Func<T, R> func)
{
    return func(t);
}

ExpensiveFindWally().Map(wally=>wally.FirstName + " " + wally.LastName)

public static R TryCC<T, R>(this T t, Func<T, R> func)
    where T : class
    where R : class
{
    if (t == null) return null;
    return func(t);
}

public static R? TryCS<T, R>(this T t, Func<T, R> func)
    where T : class
    where R : struct
{
    if (t == null) return null;
    return func(t);
}

public static R? TryCS<T, R>(this T t, Func<T, R?> func)
    where T : class
    where R : struct
{
    if (t == null) return null;
    return func(t);
}

public static R TrySC<T, R>(this T? t, Func<T, R> func)
    where T : struct
    where R : class
{
    if (t == null) return null;
    return func(t.Value);
}

public static R? TrySS<T, R>(this T? t, Func<T, R> func)
    where T : struct
    where R : struct
{
    if (t == null) return null;
    return func(t.Value);
}

public static R? TrySS<T, R>(this T? t, Func<T, R?> func)
    where T : struct
    where R : struct
{
    if (t == null) return null;
    return func(t.Value);
}

//int? bossNameLength =  Departament.Boss.TryCC(b=>b.Name).TryCS(s=>s.Length);


public static T ThrowIfNullS<T>(this T? t, string mensaje)
    where T : struct
{
    if (t == null)
        throw new NullReferenceException(mensaje);
    return t.Value;
}

public static T ThrowIfNullC<T>(this T t, string mensaje)
    where T : class
{
    if (t == null)
        throw new NullReferenceException(mensaje);
    return t;
}

public static T Do<T>(this T t, Action<T> action)
{
    action(t);
    return t;
}

//Button b = new Button{Content = "Click"}.Do(b=>Canvas.SetColumn(b,2));

public static T TryDo<T>(this T t, Action<T> action) where T : class
{
    if (t != null)
        action(t);
    return t;
}

public static T? TryDoS<T>(this T? t, Action<T> action) where T : struct
{
    if (t != null)
        action(t.Value);
    return t;
}

希望它看起来不像来自火星:)

一些工具IEnumerable: ToString(格式),ToString(函数)和Join(分隔符)。

例如:

var names = new[] { "Wagner", "Francine", "Arthur", "Bernardo" };

names.ToString("Name: {0}\n");
// Name: Wagner
// Name: Francine
// Name: Arthur
// Name: Bernardo

names.ToString(name => name.Length > 6 ? String.Format("{0} ", name) : String.Empty);
// Francine Bernardo

names.Join(" - ");
// Wagner - Francine - Arthur - Bernardo

扩展:

public static string ToString<T>(this IEnumerable<T> self, string format)
{
    return self.ToString(i => String.Format(format, i));
}

public static string ToString<T>(this IEnumerable<T> self, Func<T, object> function)
{
    var result = new StringBuilder();

    foreach (var item in self) result.Append(function(item));

    return result.ToString();
}

public static string Join<T>(this IEnumerable<T> self, string separator)
{
    return String.Join(separator, values: self.ToArray());
}
public static class StringExtensions {

    /// <summary>
    /// Parses a string into an Enum
    /// </summary>
    /// <typeparam name="T">The type of the Enum</typeparam>
    /// <param name="value">String value to parse</param>
    /// <returns>The Enum corresponding to the stringExtensions</returns>
    public static T EnumParse<T>(this string value) {
        return StringExtensions.EnumParse<T>(value, false);
    }

    public static T EnumParse<T>(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);
    }
}

将字符串解析为Enum很有用。

public enum TestEnum
{
    Bar,
    Test
}

public class Test
{
    public void Test()
    {
        TestEnum foo = "Test".EnumParse<TestEnum>();
    }
 }

这要归功于斯科特·多尔曼

——编辑Codeplex项目——

我问过Scott Dorman,他是否介意我们在Codeplex项目中发布他的代码。我从他那里得到的回答是:

感谢你对SO帖子和CodePlex项目的提醒。我赞成你对这个问题的回答。是的,代码目前在CodeProject开放许可证(http://www.codeproject.com/info/cpol10.aspx)下有效地处于公共领域。 我没有问题,这被包括在CodePlex项目,如果你想把我添加到项目(用户名是sdorman),我会添加该方法加上一些额外的枚举助手方法。

这些有用吗?

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!");