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

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

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


当前回答

GetMemberName允许在编译时安全的情况下获取带有成员名称的字符串。

public static string GetMemberName<T, TResult>(
    this T anyObject, 
    Expression<Func<T, TResult>> expression)
{
    return ((MemberExpression)expression.Body).Member.Name;
}

用法:

"blah".GetMemberName(x => x.Length); // returns "Length"

如果你没有实例,它会和一个非扩展静态方法一起出现:

public static string GetMemberName<T, TReturn>(
    Expression<Func<T, TReturn>> expression)
    where T : class
{
    return ((MemberExpression)expression.Body).Member.Name;
}

当然,这个电话看起来并不漂亮:

ReflectionUtility.GetMemberName((string) s => s.Length); // returns "Length"

如果你愿意,可以用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!

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

public static class DictionaryExtensions
{
    public static Nullable<TValue> GetValueOrNull<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key)
        where TValue : struct
    {
        TValue result;
        if (dictionary.TryGetValue(key, out result))
            return result;
        else
            return null;
    }
}

免费使用,只需在代码中提到我的名字(Janko Röbisch)。

还有一点:

public enum ParseFailBehavior
{
   ReturnNull,
   ReturnDefault,
   ThrowException
}

public static T? ParseNullableEnum<T>(this string theValue, ParseFailBehavior desiredBehavior = ParseFailBehavior.ReturnNull) where T:struct
{
   T output;
   T? result = Enum.TryParse<T>(theValue, out output) 
      ? (T?)output
      : desiredBehavior == ParseFailBehavior.ReturnDefault
         ? (T?)default(T)
         : null;

   if(result == null && desiredBehavior == ParseFailBehavior.ThrowException)
      throw new ArgumentException("Parse Failed for value {0} of enum type {1}".
         FormatWith(theValue, typeof(T).Name));       
}

这个版本需要。net 4.0;在3.5中你没有TryParse和可选参数;你就只能使用enumel . parse(),你必须尝试捕获它。它在3.5中仍然是完全可行的(而且更有用,因为enumel . parse()是oogly的,也是你唯一的其他选择):

public static T? ParseNummableEnum<T>(this string theValue)
{
    return theValue.ParseNullableEnum<T>(ParseFailBehavior.ReturnNull);
}

public static T? ParseNullableEnum<T>(this string theValue, 
    ParseFailBehavior desiredBehavior) where T:struct
{
    try
    {
        return (T?) Enum.Parse(typeof (T), theValue);
    }
    catch (Exception)
    {
        if(desiredBehavior == ParseFailBehavior.ThrowException) throw;
    }

    return desiredBehavior == ParseFailBehavior.ReturnDefault ? (T?)default(T) : null;
}

用法:

//returns null if OptionOne isn't an enum constant
var myEnum = "OptionOne".ParseNullableEnum<OptionEnum>(); 

//guarantees a return value IF the enum has a "zero" constant value (generally a good practice)
var myEnum = "OptionTwo".ParseNullableEnum<OptionEnum>(ParseFailBehavior.ReturnDefault).Value 

覆盖指定索引处的字符串的一部分。

我必须使用一个系统,它期望一些输入值是固定宽度,固定位置的字符串。

public static string Overwrite(this string s, int startIndex, string newStringValue)
{
  return s.Remove(startIndex, newStringValue.Length).Insert(startIndex, newStringValue);
}

所以我可以这样做:

string s = new String(' ',60);
s = s.Overwrite(7,"NewValue");

当使用键为字符串的字典时,使用不区分大小写的搜索返回现有的键。我们的用例是文件路径。

/// <summary>
/// Gets the key using <paramref name="caseInsensitiveKey"/> from <paramref name="dictionary"/>.
/// </summary>
/// <typeparam name="T">The dictionary value.</typeparam>
/// <param name="dictionary">The dictionary.</param>
/// <param name="caseInsensitiveKey">The case insensitive key.</param>
/// <returns>
/// An existing key; or <see cref="string.Empty"/> if not found.
/// </returns>
public static string GetKeyIgnoringCase<T>(this IDictionary<string, T> dictionary, string caseInsensitiveKey)
{
    if (string.IsNullOrEmpty(caseInsensitiveKey)) return string.Empty;
    foreach (string key in dictionary.Keys)
    {
        if (key.Equals(caseInsensitiveKey, StringComparison.InvariantCultureIgnoreCase))
        {
            return key;
        }
    }
    return string.Empty;
}