让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在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上实现和单元测试。
WhereIf()方法
var query = dc.Reviewer
.Where(r => r.FacilityID == facilityID)
.WhereIf(CheckBoxActive.Checked, r => r.IsActive);
public static IEnumerable<TSource> WhereIf<TSource>(
this IEnumerable<TSource> source,
bool condition, Func<TSource, bool> predicate)
{
if (condition)
return source.Where(predicate);
else
return source;
}
public static IQueryable<TSource> WhereIf<TSource>(
this IQueryable<TSource> source,
bool condition, Expression<Func<TSource, bool>> predicate)
{
if (condition)
return source.Where(predicate);
else
return source;
}
我还为Where()扩展方法中的索引谓词添加了重载。为了更有趣,可以添加包含额外“else”谓词的风味。
The Substring method on the string class has always felt inadequate to me. Usually when you do a substring, you know the character(s) from where you want to start, and the charachter(s) where you want to end. Thus, I've always felt that have to specify length as the second parameter is stupid. Therefore, I've written my own extension methods. One that takes a startIndex and an endIndex. And one, that takes a startText (string) and endText (string) so you can just specify the text from where to start the substring, and the text for where to end it.
注意:我不能将方法命名为。net中的Substring,因为我的第一个重载采用了与。net重载中的一个相同的参数类型。因此我将它们命名为Subsetstring。请随意添加到CodePlex…
public static class StringExtensions
{
/// <summary>
/// Returns a Subset string starting at the specified start index and ending and the specified end
/// index.
/// </summary>
/// <param name="s">The string to retrieve the subset from.</param>
/// <param name="startIndex">The specified start index for the subset.</param>
/// <param name="endIndex">The specified end index for the subset.</param>
/// <returns>A Subset string starting at the specified start index and ending and the specified end
/// index.</returns>
public static string Subsetstring(this string s, int startIndex, int endIndex)
{
if (startIndex > endIndex)
{
throw new InvalidOperationException("End Index must be after Start Index.");
}
if (startIndex < 0)
{
throw new InvalidOperationException("Start Index must be a positive number.");
}
if(endIndex <0)
{
throw new InvalidOperationException("End Index must be a positive number.");
}
return s.Substring(startIndex, (endIndex - startIndex));
}
/// <summary>
/// Finds the specified Start Text and the End Text in this string instance, and returns a string
/// containing all the text starting from startText, to the begining of endText. (endText is not
/// included.)
/// </summary>
/// <param name="s">The string to retrieve the subset from.</param>
/// <param name="startText">The Start Text to begin the Subset from.</param>
/// <param name="endText">The End Text to where the Subset goes to.</param>
/// <param name="ignoreCase">Whether or not to ignore case when comparing startText/endText to the string.</param>
/// <returns>A string containing all the text starting from startText, to the begining of endText.</returns>
public static string Subsetstring(this string s, string startText, string endText, bool ignoreCase)
{
if (string.IsNullOrEmpty(startText) || string.IsNullOrEmpty(endText))
{
throw new ArgumentException("Start Text and End Text cannot be empty.");
}
string temp = s;
if (ignoreCase)
{
temp = s.ToUpperInvariant();
startText = startText.ToUpperInvariant();
endText = endText.ToUpperInvariant();
}
int start = temp.IndexOf(startText);
int end = temp.IndexOf(endText, start);
return Subsetstring(s, start, end);
}
}
用法:
string s = "This is a tester for my cool extension method!!";
s = s.Subsetstring("tester", "cool",true);
输出:"test for my "
这是另一双我觉得用不完的鞋:
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)
c#中Smalltalk样式的if/else。
您可以自由地在codeplex上使用您使用的任何许可证
using System;
namespace SmalltalkBooleanExtensionMethods
{
public static class BooleanExtension
{
public static T ifTrue<T> (this bool aBoolean, Func<T> method)
{
if (aBoolean)
return (T)method();
else
return default(T);
}
public static void ifTrue (this bool aBoolean, Action method)
{
if (aBoolean)
method();
}
public static T ifFalse<T> (this bool aBoolean, Func<T> method)
{
if (!aBoolean)
return (T)method();
else
return default(T);
}
public static void ifFalse (this bool aBoolean, Action method)
{
if (!aBoolean)
method();
}
public static T ifTrueifFalse<T> (this Boolean aBoolean, Func<T> methodA, Func<T> methodB)
{
if (aBoolean)
return (T)methodA();
else
return (T)methodB();
}
public static void ifTrueifFalse (this Boolean aBoolean, Action methodA, Action methodB)
{
if (aBoolean)
methodA();
else
methodB();
}
}
}
你可能已经有了一个timesRepeat方法。
using System;
namespace SmalltalkBooleanExtensionMethods
{
public static class IntExtension
{
public static int timesRepeat<T>(this int x, Func<T> method)
{
for (int i = x; i > 0; i--)
{
method();
}
return x;
}
public static int timesRepeat(this int x, Action method)
{
for (int i = x; i > 0; i--)
{
method();
}
return x;
}
}
}
Nunit测试
using System;
using SmalltalkBooleanExtensionMethods;
using NUnit.Framework;
namespace SmalltalkBooleanExtensionMethodsTest
{
[TestFixture]
public class SBEMTest
{
int i;
bool itWorks;
[SetUp]
public void Init()
{
i = 0;
itWorks = false;
}
[Test()]
public void TestifTrue()
{
itWorks = (true.ifTrue(() => true));
Assert.IsTrue(itWorks);
}
[Test()]
public void TestifFalse()
{
itWorks = (false.ifFalse(() => true));
Assert.IsTrue(itWorks);
}
[Test()]
public void TestifTrueifFalse()
{
itWorks = false.ifTrueifFalse(() => false, () => true);
Assert.IsTrue(itWorks);
itWorks = false;
itWorks = true.ifTrueifFalse(() => true, () => false);
Assert.IsTrue(itWorks);
}
[Test()]
public void TestTimesRepeat()
{
(5).timesRepeat(() => i = i + 1);
Assert.AreEqual(i, 5);
}
[Test()]
public void TestVoidMethodIfTrue()
{
true.ifTrue(() => SetItWorksBooleanToTrue());
Assert.IsTrue(itWorks);
}
[Test()]
public void TestVoidMethodIfFalse()
{
false.ifFalse(() => SetItWorksBooleanToTrue());
Assert.IsTrue(itWorks);
}
public void TestVoidMethodIfTrueIfFalse()
{
true.ifTrueifFalse(() => SetItWorksBooleanToTrue(), () => SetItWorksBooleanToFalse());
false.ifTrueifFalse(() => SetItWorksBooleanToFalse(), () => SetItWorksBooleanToTrue());
Assert.IsTrue(itWorks);
}
public void TestVoidMethodTimesRepeat()
{
(5).timesRepeat(() => AddOneToi());
Assert.AreEqual(i, 5);
}
public void SetItWorksBooleanToTrue()
{
itWorks = true;
}
public void SetItWorksBooleanToFalse()
{
itWorks = false;
}
public void AddOneToi()
{
i = i + 1;
}
}
}