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

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

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


当前回答

c#中Smalltalk样式的if/else。

您可以自由地在codeplex上使用您使用的任何许可证

using System;
namespace SmalltalkBooleanExtensionMethods
{

    public static class BooleanExtension
    {
        public static T ifTrue<T> (this bool aBoolean, Func<T> method)
        {
        if (aBoolean)
            return (T)method();
        else
            return default(T);
    }

        public static void ifTrue (this bool aBoolean, Action method)
        {
            if (aBoolean)
                method();
        }


        public static T ifFalse<T> (this bool aBoolean, Func<T> method)
        {
            if (!aBoolean)
                return (T)method();
            else
                return default(T);
        }

        public static void ifFalse (this bool aBoolean, Action method)
        {
            if (!aBoolean)
                method();
        }


        public static T ifTrueifFalse<T> (this Boolean aBoolean, Func<T> methodA, Func<T> methodB)
        {
            if (aBoolean)
                return (T)methodA();
            else
                return (T)methodB();
        }

        public static void ifTrueifFalse (this Boolean aBoolean, Action methodA, Action methodB)
        {
            if (aBoolean)
                methodA();
            else
                methodB();
        }

    }


}

你可能已经有了一个timesRepeat方法。

using System;

namespace SmalltalkBooleanExtensionMethods
{
    public static class IntExtension
    {
        public static int timesRepeat<T>(this int x, Func<T> method)
        {
            for (int i = x; i > 0; i--)
            {
                method();
            }

            return x;
        }

        public static int timesRepeat(this int x, Action method)
        {
            for (int i = x; i > 0; i--)
            {
                method();
            }

            return x;
        }
    }
}

Nunit测试

using System;
using SmalltalkBooleanExtensionMethods;
using NUnit.Framework;

namespace SmalltalkBooleanExtensionMethodsTest
{
    [TestFixture]
    public class SBEMTest
    {
        int i;
        bool itWorks;

        [SetUp]
        public void Init()
        {

            i = 0;
            itWorks = false;
        }

        [Test()]
        public void TestifTrue()
        {

            itWorks = (true.ifTrue(() => true));
            Assert.IsTrue(itWorks);
        }
        [Test()]
        public void TestifFalse()
        {
            itWorks = (false.ifFalse(() => true));
            Assert.IsTrue(itWorks);
        }

        [Test()]
        public void TestifTrueifFalse()
        {
            itWorks = false.ifTrueifFalse(() => false, () => true);
            Assert.IsTrue(itWorks);
            itWorks = false;
            itWorks = true.ifTrueifFalse(() => true, () => false);
            Assert.IsTrue(itWorks);
        }

        [Test()]
        public void TestTimesRepeat()
        {
            (5).timesRepeat(() => i = i + 1);
            Assert.AreEqual(i, 5);
        }

        [Test()]
        public void TestVoidMethodIfTrue()
        {

            true.ifTrue(() => SetItWorksBooleanToTrue());
            Assert.IsTrue(itWorks);
        }

        [Test()]
        public void TestVoidMethodIfFalse()
        {

            false.ifFalse(() => SetItWorksBooleanToTrue());
            Assert.IsTrue(itWorks);
        }

        public void TestVoidMethodIfTrueIfFalse()
        {
            true.ifTrueifFalse(() => SetItWorksBooleanToTrue(), () => SetItWorksBooleanToFalse());
            false.ifTrueifFalse(() => SetItWorksBooleanToFalse(), () => SetItWorksBooleanToTrue());
            Assert.IsTrue(itWorks);

        }

        public void TestVoidMethodTimesRepeat()
        {
            (5).timesRepeat(() => AddOneToi());
            Assert.AreEqual(i, 5);
        }

        public void SetItWorksBooleanToTrue()
        {
            itWorks = true;
        }

        public void SetItWorksBooleanToFalse()
        {
            itWorks = false;
        }

        public void AddOneToi()
        {
            i = i + 1;
        }
    }
}

其他回答

轻松序列化对象为XML:

public static string ToXml<T>(this T obj) where T : class
{
    XmlSerializer s = new XmlSerializer(obj.GetType());
    using (StringWriter writer = new StringWriter())
    {
        s.Serialize(writer, obj);
        return writer.ToString();
    }
}

"<root><child>foo</child</root>".ToXml<MyCustomType>();

让我恼火的是,LINQ给了我一个OrderBy,它接受一个实现iccomparer的类作为参数,但不支持传入一个简单的匿名比较器函数。我纠正了这一点。

这个类从你的比较器函数中创建一个IComparer…

/// <summary>
///     Creates an <see cref="IComparer{T}"/> instance for the given
///     delegate function.
/// </summary>
internal class ComparerFactory<T> : IComparer<T>
{
    public static IComparer<T> Create(Func<T, T, int> comparison)
    {
        return new ComparerFactory<T>(comparison);
    }

    private readonly Func<T, T, int> _comparison;

    private ComparerFactory(Func<T, T, int> comparison)
    {
        _comparison = comparison;
    }

    #region IComparer<T> Members

    public int Compare(T x, T y)
    {
        return _comparison(x, y);
    }

    #endregion
}

...这些扩展方法暴露了可枚举对象上的新OrderBy重载。我怀疑这适用于LINQ to SQL,但它适用于LINQ to Objects。

public static class EnumerableExtensions
{
    /// <summary>
    /// Sorts the elements of a sequence in ascending order by using a specified comparison delegate.
    /// </summary>
    public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
                                                                     Func<TKey, TKey, int> comparison)
    {
        var comparer = ComparerFactory<TKey>.Create(comparison);
        return source.OrderBy(keySelector, comparer);
    }

    /// <summary>
    /// Sorts the elements of a sequence in descending order by using a specified comparison delegate.
    /// </summary>
    public static IOrderedEnumerable<TSource> OrderByDescending<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector,
                                                                               Func<TKey, TKey, int> comparison)
    {
        var comparer = ComparerFactory<TKey>.Create(comparison);
        return source.OrderByDescending(keySelector, comparer);
    }
}

如果你愿意,可以把这个放在codeplex上。

内联转换:我喜欢这个小模式。完成了Boolean, Double和DateTime。设计遵循c#的is和作为操作符。

public static Int32? AsInt32(this string s)
{
    Int32 value;
    if (Int32.TryParse(s, out value))
        return value;

    return null;
}

public static bool IsInt32(this string s)
{
    return s.AsInt32().HasValue;
}

public static Int32 ToInt32(this string s)
{
    return Int32.Parse(s);
{

一些用于使用列表的扩展:

/// <summary>
/// Wrap an object in a list
/// </summary>
public static IList<T> WrapInList<T>(this T item)
{
    List<T> result = new List<T>();
    result.Add(item);
    return result;
}

使用如:

myList = someObject.InList();

使IEnumerable包含来自一个或多个源的项,以使IEnumerable更像列表。对于高性能代码来说,这可能不是一个好主意,但对于测试来说很有用:

public static IEnumerable<T> Append<T>(this IEnumerable<T> enumerable, T newItem)
{
    foreach (T item in enumerable)
    {
        yield return item;
    }

    yield return newItem;
}

public static IEnumerable<T> Append<T>(this IEnumerable<T> enumerable, params T[] newItems)
{
    foreach (T item in enumerable)
    {
        yield return item;
    }

    foreach (T newItem in newItems)
    {
        yield return newItem;
    }
}

如使用。

someEnumeration = someEnumeration.Append(newItem);

还有其他可能的变化——例如。

someEnumeration = someEnumeration.Append(otherEnumeration);

如果你正在克隆项目,你可能还想克隆它们的列表:

public static IList<T> Clone<T>(this IEnumerable<T> source) where T: ICloneable
{
    List<T> result = new List<T>();

    foreach (T item in source)
    {
        result.Add((T)item.Clone());
    }

    return result;
}

当我使用ObservableCollection<T>时,我通常使用AddRange方法扩展它。这里的其他答案给出了这个的实现。

如果您愿意,可以将此代码放入Codeplex项目中。

在将表单输入放入数据库之前解析表单输入时,这些扩展方法对我来说非常有用

public static int? ToInt(this string input) 
{
    int val;
    if (int.TryParse(input, out val))
        return val;
    return null;
}

public static DateTime? ToDate(this string input)
{
    DateTime val;
    if (DateTime.TryParse(input, out val))
        return val;
    return null;
}

public static decimal? ToDecimal(this string input)
{
    decimal val;
    if (decimal.TryParse(input, out val))
        return val;
    return null;
}