让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在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.
这是我今天刚创建的一个。
// 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>
/// Converts any type in to an Int32
/// </summary>
/// <typeparam name="T">Any Object</typeparam>
/// <param name="value">Value to convert</param>
/// <returns>The integer, 0 if unsuccessful</returns>
public static int ToInt32<T>(this T value)
{
int result;
if (int.TryParse(value.ToString(), out result))
{
return result;
}
return 0;
}
/// <summary>
/// Converts any type in to an Int32 but if null then returns the default
/// </summary>
/// <param name="value">Value to convert</param>
/// <typeparam name="T">Any Object</typeparam>
/// <param name="defaultValue">Default to use</param>
/// <returns>The defaultValue if unsuccessful</returns>
public static int ToInt32<T>(this T value, int defaultValue)
{
int result;
if (int.TryParse(value.ToString(), out result))
{
return result;
}
return defaultValue;
}
例子:
int number = "123".ToInt32();
or:
int badNumber = "a".ToInt32(100); // Returns 100 since a is nan
有几次我发现自己想要Groovy的“安全导航”之类的东西。
从http://groovy.codehaus.org/Statements:
如果你在行走一个复杂的物体
图和不想要的
你可以抛出nullpointerexception
使用?。操作员而不是。来
执行导航。
Def foo = null Def bar =
.myMethod()断言条
= =零
那么,您认为为它添加扩展方法是一个好主意吗?
喜欢的东西:
obj.SafelyNavigate(x => x.SomeProperty.MaybeAMethod().AnotherProperty);
我认为即使它也会带来一些麻烦,这也很好。
如果你认为这是个好主意:
您认为值类型应该发生什么?,
返回默认吗?扔吗?,通过泛型约束禁用它?
吞咽NullReferenceException来实现它会太冒险吗?,
你有什么建议?,
遍历表达式树执行每个调用或成员访问似乎很困难,而且有点过度(如果可能的话),不是吗?
也许这只是一个坏主意:D,但我认为如果做得对,它是有用的。
如果没有类似的东西,你认为它有一些价值,我可能会给它一个机会,然后编辑答案。
我在我的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 --%>
<% } %>