让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在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 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。第一种情况是没有匹配项。
一些工具IEnumerable: ToString(格式),ToString(函数)和Join(分隔符)。
例如:
var names = new[] { "Wagner", "Francine", "Arthur", "Bernardo" };
names.ToString("Name: {0}\n");
// Name: Wagner
// Name: Francine
// Name: Arthur
// Name: Bernardo
names.ToString(name => name.Length > 6 ? String.Format("{0} ", name) : String.Empty);
// Francine Bernardo
names.Join(" - ");
// Wagner - Francine - Arthur - Bernardo
扩展:
public static string ToString<T>(this IEnumerable<T> self, string format)
{
return self.ToString(i => String.Format(format, i));
}
public static string ToString<T>(this IEnumerable<T> self, Func<T, object> function)
{
var result = new StringBuilder();
foreach (var item in self) result.Append(function(item));
return result.ToString();
}
public static string Join<T>(this IEnumerable<T> self, string separator)
{
return String.Join(separator, values: self.ToArray());
}
您可能已经知道扩展方法的一个有趣用法是作为一种mixin。一些扩展方法,比如XmlSerializable,几乎污染了所有类;这对大多数人来说没有意义,比如Thread和SqlConnection。
一些功能应该显式地混合到希望拥有它的类中。我对这种类型提出了一种新的表示法,以M为前缀。
XmlSerializable是这样的:
public interface MXmlSerializable { }
public static class XmlSerializable {
public static string ToXml(this MXmlSerializable self) {
if (self == null) throw new ArgumentNullException();
var serializer = new XmlSerializer(self.GetType());
using (var writer = new StringWriter()) {
serializer.Serialize(writer, self);
return writer.GetStringBuilder().ToString();
}
}
public static T FromXml<T>(string xml) where T : MXmlSerializable {
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(new StringReader(xml));
}
}
然后一个类将其混合:
public class Customer : MXmlSerializable {
public string Name { get; set; }
public bool Preferred { get; set; }
}
用法很简单:
var customer = new Customer {
Name = "Guybrush Threepwood",
Preferred = true };
var xml = customer.ToXml();
如果您喜欢这个想法,您可以在项目中为有用的mixin创建一个新的名称空间。你怎么看?
哦,顺便说一下,我认为大多数扩展方法都应该显式地测试null。