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

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

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


当前回答

讨厌这种代码?

CloneableClass cc1 = new CloneableClass ();
CloneableClass cc2 = null;
CloneableClass cc3 = null;

cc3 = (CloneableClass) cc1.Clone (); // this is ok
cc3 = cc2.Clone (); // this throws null ref exception
// code to handle both cases
cc3 = cc1 != null ? (CloneableClass) cc1.Clone () : null;

它有点笨拙,所以我用这个扩展替换它,我称之为CloneOrNull -

public static T CloneOrNull<T> (this T self) where T : class, ICloneable
{
    if (self == null) return null;
    return (T) self.Clone ();
}

用法如下:

CloneableClass cc1 = new CloneableClass ();
CloneableClass cc2 = null;
CloneableClass cc3 = null;

cc3 = cc1.CloneOrNull (); // clone of cc1
cc3 = cc2.CloneOrNull (); // null
// look mom, no casts!

请随意在任何地方使用这个!

其他回答

我已经实现了一个扩展方法包(在http://foop.codeplex.com/上可用),其中一些是我日常使用的:

// the most beloved extension method for me is Pipe:
<%= variable.Pipe(x => this.SomeFunction(x)).Pipe(y =>
{
    ...;
    return this.SomeOtherFunction(y);
}) %>

var d = 28.December(2009); // some extension methods for creating DateTime
DateTime justDatePart = d.JustDate();
TimeSpan justTimePart = d.JustTime();
var nextTime = d.Add(5.Hours());

using(StreamReader reader = new StreamReader("lines-of-data-file-for-example")) {
    ...
    // for reading streams line by line and usable in LINQ
    var query = from line in reader.Lines(); 
                where line.Contains(_today)
                select new { Parts = PartsOf(line), Time = _now };
}

500.Sleep();

XmlSerialize and XmlDeserialize

IsNull and IsNotNull

IfTrue, IfFalse and Iff:
true.IfTrue(() => Console.WriteLine("it is true then!");

IfNull and IfNotNull

将字符串的长度减少到toLength,并在缩短的字符串的末尾添加一个额外的字符串,以表示字符串被缩短(默认值…)

public static string Shorten(this string str, int toLength, string cutOffReplacement = " ...")
{
    if (string.IsNullOrEmpty(str) || str.Length <= toLength)
        return str;
    else
        return str.Remove(toLength) + cutOffReplacement;
}
public static class ComparableExtensions
{
  public static bool Between<T>(this T actual, T lower, T upper) where T : IComparable<T>
  {
    return actual.CompareTo(lower) >= 0 && actual.CompareTo(upper) < 0;
  }
}

例子:

if (myNumber.Between(3,7))
{
  // ....
}
static string Format( this string str,
                    , params Expression<Func<string,object>>[] args)
{
    var parameters = args.ToDictionary
                        ( e=>string.Format("{{{0}}}",e.Parameters[0].Name)
                        , e=>e.Compile()(e.Parameters[0].Name));

    var sb = new StringBuilder(str);
    foreach(var kv in parameters)
    {
        sb.Replace( kv.Key
                  , kv.Value != null ? kv.Value.ToString() : "");
    }

    return sb.ToString();
}

有了上面的扩展,你可以这样写:

var str = "{foo} {bar} {baz}".Format(foo=>foo, bar=>2, baz=>new object());

你会得到"foo 2 System.Object"。

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

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