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

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

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


当前回答

这一个是MVC,它添加了生成一个<label />标签到Html变量的能力,在每个ViewPage中可用。希望它能对其他试图开发类似扩展的人有所帮助。

Use:

<%= Html.Label("LabelId", "ForId", "Text")%>

输出:

<label id="LabelId" for="ForId">Text</label>

代码:

public static class HtmlHelperExtensions
{
    public static string Label(this HtmlHelper Html, string @for, string text)
    {
        return Html.Label(null, @for, text);
    }

    public static string Label(this HtmlHelper Html, string @for, string text, object htmlAttributes)
    {
        return Html.Label(null, @for, text, htmlAttributes);
    }

    public static string Label(this HtmlHelper Html, string @for, string text, IDictionary<string, object> htmlAttributes)
    {
        return Html.Label(null, @for, text, htmlAttributes);
    }

    public static string Label(this HtmlHelper Html, string id, string @for, string text)
    {
        return Html.Label(id, @for, text, null);
    }

    public static string Label(this HtmlHelper Html, string id, string @for, string text, object htmlAttributes)
    {
        return Html.Label(id, @for, text, new RouteValueDictionary(htmlAttributes));
    }

    public static string Label(this HtmlHelper Html, string id, string @for, string text, IDictionary<string, object> htmlAttributes)
    {
        TagBuilder tag = new TagBuilder("label");

        tag.MergeAttributes(htmlAttributes);

        if (!string.IsNullOrEmpty(id))
            tag.MergeAttribute("id", Html.AttributeEncode(id));

        tag.MergeAttribute("for", Html.AttributeEncode(@for));

        tag.SetInnerText(Html.Encode(text));

        return tag.ToString(TagRenderMode.Normal);
    }
}

其他回答

下面是我用来减少提取单个属性的一些方法:

public static T GetAttribute<T>(this ICustomAttributeProvider provider, bool inherit = false, int index = 0) where T : Attribute
{
    return provider.GetAttribute(typeof(T), inherit, index) as T;
}

public static Attribute GetAttribute(this ICustomAttributeProvider provider, Type type, bool inherit = false, int index = 0)
{
    bool exists = provider.IsDefined(type, inherit);
    if (!exists)
    {
        return null;
    }

    object[] attributes = provider.GetCustomAttributes(type, inherit);
    if (attributes != null && attributes.Length != 0)
    {
        return attributes[index] as Attribute;
    }
    else
    {
        return null;
    }
}

用法(枚举描述hack的实现):

public static string GetDescription(this Enum value)
{
    var fieldInfo = value.GetType().GetField(value.ToString());
    var attribute = fieldInfo.GetAttribute<DescriptionAttribute>();
    return attribute != null ? attribute.Description : null;
}

请随意将其包含在CodePlex项目中!

// Values ordered true/false
// True/false values separated by a capital letter
// Only two values allowed
// ---------------------------
// Limited, but could be useful
public enum BooleanFormat
{
    OneZero,
    YN,
    YesNo,
    TF,
    TrueFalse,
    PassFail,
    YepNope
}

public static class BooleanExtension
{
    /// <summary>
    /// Converts the boolean value of this instance to the specified string value. 
    /// </summary>
    private static string ToString(this bool value, string passValue, string failValue)
    {
        return value ? passValue : failValue;
    }

    /// <summary>
    /// Converts the boolean value of this instance to a string. 
    /// </summary>
    /// <param name="booleanFormat">A BooleanFormat value. 
    /// Example: BooleanFormat.PassFail would return "Pass" if true and "Fail" if false.</param>
    /// <returns>Boolean formatted string</returns>
    public static string ToString(this bool value, BooleanFormat booleanFormat)
    {
        string booleanFormatString = Enum.GetName(booleanFormat.GetType(), booleanFormat);
        return ParseBooleanString(value, booleanFormatString);      
    }

    // Parses boolean format strings, not optimized
    private static string ParseBooleanString(bool value, string booleanFormatString)
    {
        StringBuilder trueString = new StringBuilder();
        StringBuilder falseString = new StringBuilder();

        int charCount = booleanFormatString.Length;

        bool isTrueString = true;

        for (int i = 0; i != charCount; i++)
        {
            if (char.IsUpper(booleanFormatString[i]) && i != 0)
                isTrueString = false;

            if (isTrueString)
                trueString.Append(booleanFormatString[i]);
            else
                falseString.Append(booleanFormatString[i]);
        }

        return (value == true ? trueString.ToString() : falseString.ToString());
    }

二分查找:

public static T BinarySearch<T, TKey>(this IList<T> list, Func<T, TKey> keySelector, TKey key)
        where TKey : IComparable<TKey>
{
    int min = 0;
    int max = list.Count;
    int index = 0;
    while (min < max)
    {
        int mid = (max + min) / 2;
        T midItem = list[mid];
        TKey midKey = keySelector(midItem);
        int comp = midKey.CompareTo(key);
        if (comp < 0)
        {
            min = mid + 1;
        }
        else if (comp > 0)
        {
            max = mid - 1;
        }
        else
        {
            return midItem;
        }
    }
    if (min == max &&
        keySelector(list[min]).CompareTo(key) == 0)
    {
        return list[min];
    }
    throw new InvalidOperationException("Item not found");
}

用法(假设列表按Id排序):

var item = list.BinarySearch(i => i.Id, 42);

它抛出InvalidOperationException的事实可能看起来很奇怪,但这就是Enumerable。第一种情况是没有匹配项。

我发现这个方法很有用

public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> pSeq)
{
    return pSeq ?? Enumerable.Empty<T>();
}

它在调用代码中删除空检查。现在你可以

MyList.EmptyIfNull().Where(....)

用于ienumables的ForEach

public static class FrameworkExtensions
{
    // a map function
    public static void ForEach<T>(this IEnumerable<T> @enum, Action<T> mapFunction)
    {
        foreach (var item in @enum) mapFunction(item);
    }
}

天真的例子:

var buttons = GetListOfButtons() as IEnumerable<Button>;

// click all buttons
buttons.ForEach(b => b.Click());

酷的例子:

// no need to type the same assignment 3 times, just
// new[] up an array and use foreach + lambda
// everything is properly inferred by csc :-)
new { itemA, itemB, itemC }
    .ForEach(item => {
        item.Number = 1;
        item.Str = "Hello World!";
    });

注意:

这与Select不同,因为Select期望函数返回转换为另一个列表的内容。

ForEach只是允许您为每个项执行一些东西,而不需要任何转换/数据操作。

我这样做,所以我可以在一个更函数式的风格编程,我很惊讶,列表有一个ForEach,而IEnumerable没有。

把这个放到codeplex项目中