让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在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 class FluentOrderingExtensions
public class FluentOrderer<T> : IEnumerable<T>
{
internal List<Comparison<T>> Comparers = new List<Comparison<T>>();
internal IEnumerable<T> Source;
public FluentOrderer(IEnumerable<T> source)
{
Source = source;
}
#region Implementation of IEnumerable
public IEnumerator<T> GetEnumerator()
{
var workingArray = Source.ToArray();
Array.Sort(workingArray, IterativeComparison);
foreach(var element in workingArray) yield return element;
}
private int IterativeComparison(T a, T b)
{
foreach (var comparer in Comparers)
{
var result = comparer(a,b);
if(result != 0) return result;
}
return 0;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
public static FluentOrderer<T> OrderFluentlyBy<T,TResult>(this IEnumerable<T> source, Func<T,TResult> predicate)
where TResult : IComparable<TResult>
{
var result = new FluentOrderer<T>(source);
result.Comparers.Add((a,b)=>predicate(a).CompareTo(predicate(b)));
return result;
}
public static FluentOrderer<T> OrderFluentlyByDescending<T,TResult>(this IEnumerable<T> source, Func<T,TResult> predicate)
where TResult : IComparable<TResult>
{
var result = new FluentOrderer<T>(source);
result.Comparers.Add((a,b)=>predicate(a).CompareTo(predicate(b)) * -1);
return result;
}
public static FluentOrderer<T> ThenBy<T, TResult>(this FluentOrderer<T> source, Func<T, TResult> predicate)
where TResult : IComparable<TResult>
{
source.Comparers.Add((a, b) => predicate(a).CompareTo(predicate(b)));
return source;
}
public static FluentOrderer<T> ThenByDescending<T, TResult>(this FluentOrderer<T> source, Func<T, TResult> predicate)
where TResult : IComparable<TResult>
{
source.Comparers.Add((a, b) => predicate(a).CompareTo(predicate(b)) * -1);
return source;
}
}
用法:
var myFluentlyOrderedList = GetABunchOfComplexObjects()
.OrderFluentlyBy(x=>x.PropertyA)
.ThenByDescending(x=>x.PropertyB)
.ThenBy(x=>x.SomeMethod())
.ThenBy(x=>SomeOtherMethodAppliedTo(x))
.ToList();
... 当然,假设所有的谓词都返回与自身icomcomparable的类型。如果使用像MergeSort这样的稳定排序,而不是。net内置的快速排序,它会更好地工作,但它提供了类似于SQL的可读多字段排序能力(无论如何,它是方法链所能获得的最接近的功能)。您可以通过定义重载来接受比较lambda,而不是基于谓词创建它,从而扩展它以容纳非IComparable的成员。
EDIT: A little explanation, since the commenter got some upticks: this set of methods improves upon the basic OrderBy() functionality by allowing you to sort based on multiple fields in descending order of importance. A real-world example would be sorting a list of invoices by customer, then by invoice number (or invoice date). Other methods of getting the data in this order either wouldn't work (OrderBy() uses an unstable sort, so it cannot be chained) or would be inefficient and not look like it does what you're trying to do.
而与MVC工作,有很多if语句,我只关心或真或假,打印null,或字符串。在另一种情况下,我想到了:
public static TResult WhenTrue<TResult>(this Boolean value, Func<TResult> expression)
{
return value ? expression() : default(TResult);
}
public static TResult WhenTrue<TResult>(this Boolean value, TResult content)
{
return value ? content : default(TResult);
}
public static TResult WhenFalse<TResult>(this Boolean value, Func<TResult> expression)
{
return !value ? expression() : default(TResult);
}
public static TResult WhenFalse<TResult>(this Boolean value, TResult content)
{
return !value ? content : default(TResult);
}
它允许我改变<%= (someBool) ?print y:字符串。将%>空为<%= someBool。WhenTrue("print y") %>。
我只在我的视图中使用它,在这里我混合了代码和HTML,在代码文件中编写“更长的”版本更清楚。
对于Winform控件:
/// <summary>
/// Returns whether the function is being executed during design time in Visual Studio.
/// </summary>
public static bool IsDesignTime(this Control control)
{
if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
return true;
}
if (control.Site != null && control.Site.DesignMode)
{
return true;
}
var parent = control.Parent;
while (parent != null)
{
if (parent.Site != null && parent.Site.DesignMode)
{
return true;
}
parent = parent.Parent;
}
return false;
}
/// <summary>
/// Sets the DropDownWidth to ensure that no item's text is cut off.
/// </summary>
public static void SetDropDownWidth(this ComboBox comboBox)
{
var g = comboBox.CreateGraphics();
var font = comboBox.Font;
float maxWidth = 0;
foreach (var item in comboBox.Items)
{
maxWidth = Math.Max(maxWidth, g.MeasureString(item.ToString(), font).Width);
}
if (comboBox.Items.Count > comboBox.MaxDropDownItems)
{
maxWidth += SystemInformation.VerticalScrollBarWidth;
}
comboBox.DropDownWidth = Math.Max(comboBox.Width, Convert.ToInt32(maxWidth));
}
IsDesignTime用法:
public class SomeForm : Form
{
public SomeForm()
{
InitializeComponent();
if (this.IsDesignTime())
{
return;
}
// Do something that makes the visual studio crash or hang if we're in design time,
// but any other time executes just fine
}
}
SetDropdownWidth用法:
ComboBox cbo = new ComboBox { Width = 50 };
cbo.Items.Add("Short");
cbo.Items.Add("A little longer");
cbo.Items.Add("Holy cow, this is a really, really long item. How in the world will it fit?");
cbo.SetDropDownWidth();
我忘了说,请随意在Codeplex上使用这些…