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

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

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


当前回答

类似于上面的字符串As和Is,但对所有对象都是全局的。

这很简单,但我经常使用这些方法来缓解拳击中的parens爆炸。

public static class ExtensionMethods_Object
{
    [DebuggerStepThrough()]
    public static bool Is<T>(this object item) where T : class
    {
        return item is T;
    }

    [DebuggerStepThrough()]
    public static bool IsNot<T>(this object item) where T : class
    {
        return !(item.Is<T>());
    }

    [DebuggerStepThrough()]
    public static T As<T>(this object item) where T : class
    {
        return item as T;
    }
}

我很高兴这段代码能在codeplex上使用,事实上它已经在使用了。

其他回答

每n个字符换行一个字符串。

public static string WrapAt(this string str, int WrapPos)
{
    if (string.IsNullOrEmpty(str))
        throw new ArgumentNullException("str", "Cannot wrap a null string");
    str = str.Replace("\r", "").Replace("\n", "");

    if (str.Length <= WrapPos)
        return str;

    for (int i = str.Length; i >= 0; i--)
        if (i % WrapPos == 0 && i > 0 && i != str.Length)
            str = str.Insert(i, "\r\n");
    return str;
}

类似于上面的字符串As和Is,但对所有对象都是全局的。

这很简单,但我经常使用这些方法来缓解拳击中的parens爆炸。

public static class ExtensionMethods_Object
{
    [DebuggerStepThrough()]
    public static bool Is<T>(this object item) where T : class
    {
        return item is T;
    }

    [DebuggerStepThrough()]
    public static bool IsNot<T>(this object item) where T : class
    {
        return !(item.Is<T>());
    }

    [DebuggerStepThrough()]
    public static T As<T>(this object item) where T : class
    {
        return item as T;
    }
}

我很高兴这段代码能在codeplex上使用,事实上它已经在使用了。

用于winforms填充组合框:

List<MyObject> myObjects = new List<MyObject>() { 
    new MyObject() {Name = "a", Id = 0}, 
    new MyObject() {Name = "b", Id = 1}, 
    new MyObject() {Name = "c", Id = 2} }
comboBox.FillDataSource<MyObject>(myObjects, x => x.Name);

扩展方法:

/** <summary>Fills the System.Windows.Forms.ComboBox object DataSource with a 
 * list of T objects.</summary>
 * <param name="values">The list of T objects.</param>
 * <param name="displayedValue">A function to apply to each element to get the 
 * display value.</param>
 */
public static void FillDataSource<T>(this ComboBox comboBox, List<T> values,
    Func<T, String> displayedValue) {

    // Create dataTable
    DataTable data = new DataTable();
    data.Columns.Add("ValueMember", typeof(T));
    data.Columns.Add("DisplayMember");

    for (int i = 0; i < values.Count; i++) {
        // For each value/displayed value

        // Create new row with value & displayed value
        DataRow dr = data.NewRow();
        dr["ValueMember"] = values[i];
        dr["DisplayMember"] = displayedValue(values[i]) ?? "";
        // Add row to the dataTable
        data.Rows.Add(dr);
    }

    // Bind datasource to the comboBox
    comboBox.DataSource = data;
    comboBox.ValueMember = "ValueMember";
    comboBox.DisplayMember = "DisplayMember";
}

下面是我们工作代码库中的一个有趣的例子。在作业线程上遍历一个昂贵的lazy-eval枚举对象,并通过一个可观察对象推回结果。

public static IObservable<T> ToAsyncObservable<T>(this IEnumerable<T> @this)
{
    return Observable.Create<T>(observer =>
    {
        var task = new Task(() =>
        {
            try
            {
                @this.Run(observer.OnNext);
                observer.OnCompleted();
            }
            catch (Exception e)
            {
                observer.OnError(e);
            }
        });

        task.Start();

        return () => { };
    });
}

愚蠢的示例:

new DirectoryInfo(@"c:\program files")
    .EnumerateFiles("*", SearchOption.AllDirectories)
    .ToAsyncObservable()
    .BufferWithTime(TimeSpan.FromSeconds(0.5))
    .ObserveOnDispatcher()
    .Subscribe(
        l => Console.WriteLine("{0} received", l.Count),
        () => Console.WriteLine("Done!"));

for (;;)
{
    Thread.Sleep(10);
    Dispatcher.PushFrame(new DispatcherFrame());
}

显然,这个扩展将是无用的,如果你不使用辉煌的响应式扩展!

感谢评论中的Richard,这个扩展方法是不必要的。RX已经有一个扩展方法“tooobservable”,它接受IScheduler。那就用这个吧!

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

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();