让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在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上实现和单元测试。
在单元测试中很有用:
public static IList<T> Clone<T>(this IList<T> list) where T : ICloneable
{
var ret = new List<T>(list.Count);
foreach (var item in list)
ret.Add((T)item.Clone());
// done
return ret;
}
像TWith2Sugars这样的一系列,交替缩短语法:
public static long? ToNullableInt64(this string val)
{
long ret;
return Int64.TryParse(val, out ret) ? ret : new long?();
}
最后,在BCL中是否已经有一些东西做了下面的事情?
public static void Split<T>(this T[] array,
Func<T,bool> determinator,
IList<T> onTrue,
IList<T> onFalse)
{
if (onTrue == null)
onTrue = new List<T>();
else
onTrue.Clear();
if (onFalse == null)
onFalse = new List<T>();
else
onFalse.Clear();
if (determinator == null)
return;
foreach (var item in array)
{
if (determinator(item))
onTrue.Add(item);
else
onFalse.Add(item);
}
}
这是我写的唯一一个我经常使用的扩展。
它使得用System.Net.Mail发送电子邮件更容易一些。
public static class MailExtension
{
// GetEmailCreditial(out strServer) gets credentials from an XML file
public static void Send(this MailMessage email)
{
string strServer = String.Empty;
NetworkCredential credentials = GetEmailCreditial(out strServer);
SmtpClient client = new SmtpClient(strServer) { Credentials = credentials };
client.Send(email);
}
public static void Send(this IEnumerable<MailMessage> emails)
{
string strServer = String.Empty;
NetworkCredential credentials = GetEmailCreditial(out strServer);
SmtpClient client = new SmtpClient(strServer) { Credentials = credentials };
foreach (MailMessage email in emails)
client.Send(email);
}
}
// Example of use:
new MailMessage("info@myDomain.com","you@gmail.com","This is an important Subject", "Body goes here").Send();
//Assume email1,email2,email3 are MailMessage objects
new List<MailMessage>(){email1, email2, email}.Send();
我在我的web项目中使用这些,主要是MVC。我为ViewData和TempData写了一些这样的代码
/// <summary>
/// Checks the Request.QueryString for the specified value and returns it, if none
/// is found then the default value is returned instead
/// </summary>
public static T QueryValue<T>(this HtmlHelper helper, string param, T defaultValue) {
object value = HttpContext.Current.Request.QueryString[param] as object;
if (value == null) { return defaultValue; }
try {
return (T)Convert.ChangeType(value, typeof(T));
} catch (Exception) {
return defaultValue;
}
}
这样我就可以写……
<% if (Html.QueryValue("login", false)) { %>
<div>Welcome Back!</div>
<% } else { %>
<%-- Render the control or something --%>
<% } %>
// Checks for an empty collection, and sends the value set in the default constructor for the desired field
public static TResult MinGuarded<T, TResult>(this IEnumerable<T> items, Func<T, TResult> expression) where T : new() {
if(items.IsEmpty()) {
return (new List<T> { new T() }).Min(expression);
}
return items.Min(expression);
}
// Checks for an empty collection, and sends the value set in the default constructor for the desired field
public static TResult MaxGuarded<T, TResult>(this IEnumerable<T> items, Func<T, TResult> expression) where T : new() {
if(items.IsEmpty()) {
return (new List<T> { new T() }).Max(expression);
}
return items.Max(expression);
}
我不确定是否有更好的方法来做到这一点,但这个扩展是非常有用的,每当我想要控制我的对象中的字段的默认值。
例如,如果我想控制DateTime的值,并希望根据我的业务逻辑进行设置,那么我可以在默认构造函数中这样做。否则,它将显示为DateTime.MinDate。
// 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());
}
一些用于使用列表的扩展:
/// <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项目中。