让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在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上实现和单元测试。
从集合中加载默认设置的一种更简单的方法(在现实生活中,我使用它来填充来自任何来源的设置,包括命令行,ClickOnce URL参数等):
public static void LoadFrom(this ApplicationSettingsBase settings, NameValueCollection configuration)
{
if (configuration != null)
foreach (string key in configuration.AllKeys)
if (!String.IsNullOrEmpty(key))
try
{
settings[key] = configuration.Get(key);
}
catch (SettingsPropertyNotFoundException)
{
// handle bad arguments as you wish
}
}
例子:
Settings.Default.LoadFrom(new NameValueCollection() { { "Setting1", "Value1" }, { "Setting2", "Value2" } });
灵感来自弦。IsNullOrEmpty
要验证给定的List为空或空
public static bool IsNullOrEmpty<TSource>(this List<TSource> src)
{
return (src == null || src.Count == 0);
}
这个是验证给定的两个文件和属性
public static bool Compare(this FileInfo f1, FileInfo f2, string propertyName)
{
try
{
PropertyInfo p1 = f1.GetType().GetProperty(propertyName);
PropertyInfo p2 = f2.GetType().GetProperty(propertyName);
if (p1.GetValue(f1, null) == p2.GetValue(f1, null))
return true;
}
catch (Exception ex)
{
return false;
}
return false;
}
像这样使用它
FileInfo fo = new FileInfo("c:\\netlog.txt");
FileInfo f1 = new FileInfo("c:\\regkey.txt");
fo.compare(f1, "CreationTime");
这是我今天刚创建的一个。
// requires .NET 4
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
TReturn elseValue = default(TReturn)) where TIn : class
{ return obj != null ? func(obj) : elseValue; }
// versions for CLR 2, which doesn't support optional params
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func,
TReturn elseValue) where TIn : class
{ return obj != null ? func(obj) : elseValue; }
public static TReturn NullOr<TIn, TReturn>(this TIn obj, Func<TIn, TReturn> func)
where TIn : class
{ return obj != null ? func(obj) : default(TReturn); }
它让你这样做:
var lname = thingy.NullOr(t => t.Name).NullOr(n => n.ToLower());
哪个比这个更流畅,(依我看)更容易阅读:
var lname = (thingy != null ? thingy.Name : null) != null
? thingy.Name.ToLower() : null;
我使用以下扩展来扩展所有的集合(也许有人发现这些有用):
/// <summary>
/// Collection Helper
/// </summary>
/// <remarks>
/// Use IEnumerable by default, but when altering or getting item at index use IList.
/// </remarks>
public static class CollectionHelper
{
#region Alter;
/// <summary>
/// Swap item to another place
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="IndexA">Index a</param>
/// <param name="IndexB">Index b</param>
/// <returns>New collection</returns>
public static IList<T> Swap<T>(this IList<T> @this, Int32 IndexA, Int32 IndexB)
{
T Temp = @this[IndexA];
@this[IndexA] = @this[IndexB];
@this[IndexB] = Temp;
return @this;
}
/// <summary>
/// Swap item to the left
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index</param>
/// <returns>New collection</returns>
public static IList<T> SwapLeft<T>(this IList<T> @this, Int32 Index)
{
return @this.Swap(Index, Index - 1);
}
/// <summary>
/// Swap item to the right
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index</param>
/// <returns>New collection</returns>
public static IList<T> SwapRight<T>(this IList<T> @this, Int32 Index)
{
return @this.Swap(Index, Index + 1);
}
#endregion Alter;
#region Action;
/// <summary>
/// Execute action at specified index
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index</param>
/// <param name="ActionAt">Action to execute</param>
/// <returns>New collection</returns>
public static IList<T> ActionAt<T>(this IList<T> @this, Int32 Index, Action<T> ActionAt)
{
ActionAt(@this[Index]);
return @this;
}
#endregion Action;
#region Randomize;
/// <summary>
/// Take random items
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Count">Number of items to take</param>
/// <returns>New collection</returns>
public static IEnumerable<T> TakeRandom<T>(this IEnumerable<T> @this, Int32 Count)
{
return @this.Shuffle().Take(Count);
}
/// <summary>
/// Take random item
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <returns>Item</returns>
public static T TakeRandom<T>(this IEnumerable<T> @this)
{
return @this.TakeRandom(1).Single();
}
/// <summary>
/// Shuffle list
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <returns>New collection</returns>
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> @this)
{
return @this.OrderBy(Item => Guid.NewGuid());
}
#endregion Randomize;
#region Navigate;
/// <summary>
/// Get next item in collection and give first item, when last item is selected;
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index in collection</param>
/// <returns>Next item</returns>
public static T Next<T>(this IList<T> @this, ref Int32 Index)
{
Index = ++Index >= 0 && Index < @this.Count ? Index : 0;
return @this[Index];
}
/// <summary>
/// Get previous item in collection and give last item, when first item is selected;
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index in collection</param>
/// <returns>Previous item</returns>
public static T Previous<T>(this IList<T> @this, ref Int32 Index)
{
Index = --Index >= 0 && Index < @this.Count ? Index : @this.Count - 1;
return @this[Index];
}
#endregion Navigate;
#region Clone;
/// <summary>
///
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <returns>Cloned collection</returns>
public static IEnumerable<T> Clone<T>(this IEnumerable<T> @this) where T : ICloneable
{
return @this.Select(Item => (T)Item.Clone());
}
#endregion Clone;
#region String;
/// <summary>
/// Joins multiple string with Separator
/// </summary>
/// <param name="this">Collection</param>
/// <param name="Separator">Separator</param>
/// <returns>Joined string</returns>
public static String Join(this IEnumerable<String> @this, String Separator = "")
{
return String.Join(Separator, @this);
}
#endregion String;
}
这是另一双我觉得用不完的鞋:
public static T ObjectWithMin<T, TResult>(this IEnumerable<T> sequence, Func<T, TResult> predicate)
where T : class
where TResult : IComparable
{
if (!sequence.Any()) return null;
//get the first object with its predicate value
var seed = sequence.Select(x => new {Object = x, Value = predicate(x)}).FirstOrDefault();
//compare against all others, replacing the accumulator with the lesser value
//tie goes to first object found
return
sequence.Select(x => new {Object = x, Value = predicate(x)})
.Aggregate(seed,(acc, x) => acc.Value.CompareTo(x.Value) <= 0 ? acc : x).Object;
}
public static T ObjectWithMax<T, TResult>(this IEnumerable<T> sequence, Func<T, TResult> predicate)
where T : class
where TResult : IComparable
{
if (!sequence.Any()) return null;
//get the first object with its predicate value
var seed = sequence.Select(x => new {Object = x, Value = predicate(x)}).FirstOrDefault();
//compare against all others, replacing the accumulator with the greater value
//tie goes to last object found
return
sequence.Select(x => new {Object = x, Value = predicate(x)})
.Aggregate(seed, (acc, x) => acc.Value.CompareTo(x.Value) > 0 ? acc : x).Object;
}
用法:
var myObject = myList.ObjectWithMin(x=>x.PropA);
这些方法基本上取代了像
var myObject = myList.OrderBy(x=>x.PropA).FirstOrDefault(); //O(nlog(n)) and unstable
and
var myObject = myList.Where(x=>x.PropA == myList.Min(x=>x.PropA)).FirstOrDefault(); //O(N^2) but stable
and
var minValue = myList.Min(x=>x.PropA);
var myObject = myList.Where(x=>x.PropA == minValue).FirstOrDefault(); //not a one-liner, and though linear and stable it's slower (evaluates the enumerable twice)