让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在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 EnumerableExtensions
{
[Pure]
public static U MapReduce<T, U>(this IEnumerable<T> enumerable, Func<T, U> map, Func<U, U, U> reduce)
{
CodeContract.RequiresAlways(enumerable != null);
CodeContract.RequiresAlways(enumerable.Skip(1).Any());
CodeContract.RequiresAlways(map != null);
CodeContract.RequiresAlways(reduce != null);
return enumerable.AsParallel().Select(map).Aggregate(reduce);
}
[Pure]
public static U MapReduce<T, U>(this IList<T> list, Func<T, U> map, Func<U, U, U> reduce)
{
CodeContract.RequiresAlways(list != null);
CodeContract.RequiresAlways(list.Count >= 2);
CodeContract.RequiresAlways(map != null);
CodeContract.RequiresAlways(reduce != null);
U result = map(list[0]);
for (int i = 1; i < list.Count; i++)
{
result = reduce(result,map(list[i]));
}
return result;
}
//Parallel version; creates garbage
[Pure]
public static U MapReduce<T, U>(this IList<T> list, Func<T, U> map, Func<U, U, U> reduce)
{
CodeContract.RequiresAlways(list != null);
CodeContract.RequiresAlways(list.Skip(1).Any());
CodeContract.RequiresAlways(map != null);
CodeContract.RequiresAlways(reduce != null);
U[] mapped = new U[list.Count];
Parallel.For(0, mapped.Length, i =>
{
mapped[i] = map(list[i]);
});
U result = mapped[0];
for (int i = 1; i < list.Count; i++)
{
result = reduce(result, mapped[i]);
}
return result;
}
}
static string Format( this string str,
, params Expression<Func<string,object>>[] args)
{
var parameters = args.ToDictionary
( e=>string.Format("{{{0}}}",e.Parameters[0].Name)
, e=>e.Compile()(e.Parameters[0].Name));
var sb = new StringBuilder(str);
foreach(var kv in parameters)
{
sb.Replace( kv.Key
, kv.Value != null ? kv.Value.ToString() : "");
}
return sb.ToString();
}
有了上面的扩展,你可以这样写:
var str = "{foo} {bar} {baz}".Format(foo=>foo, bar=>2, baz=>new object());
你会得到"foo 2 System.Object"。
这是罗马数字的to-and-from。不常用,但可能很方便。用法:
if ("IV".IsValidRomanNumeral())
{
// Do useful stuff with the number 4.
}
Console.WriteLine("MMMDCCCLXXXVIII".ParseRomanNumeral());
Console.WriteLine(3888.ToRomanNumeralString());
源:
public static class RomanNumeralExtensions
{
private const int NumberOfRomanNumeralMaps = 13;
private static readonly Dictionary<string, int> romanNumerals =
new Dictionary<string, int>(NumberOfRomanNumeralMaps)
{
{ "M", 1000 },
{ "CM", 900 },
{ "D", 500 },
{ "CD", 400 },
{ "C", 100 },
{ "XC", 90 },
{ "L", 50 },
{ "XL", 40 },
{ "X", 10 },
{ "IX", 9 },
{ "V", 5 },
{ "IV", 4 },
{ "I", 1 }
};
private static readonly Regex validRomanNumeral = new Regex(
"^(?i:(?=[MDCLXVI])((M{0,3})((C[DM])|(D?C{0,3}))"
+ "?((X[LC])|(L?XX{0,2})|L)?((I[VX])|(V?(II{0,2}))|V)?))$",
RegexOptions.Compiled);
public static bool IsValidRomanNumeral(this string value)
{
return validRomanNumeral.IsMatch(value);
}
public static int ParseRomanNumeral(this string value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
value = value.ToUpperInvariant().Trim();
var length = value.Length;
if ((length == 0) || !value.IsValidRomanNumeral())
{
throw new ArgumentException("Empty or invalid Roman numeral string.", "value");
}
var total = 0;
var i = length;
while (i > 0)
{
var digit = romanNumerals[value[--i].ToString()];
if (i > 0)
{
var previousDigit = romanNumerals[value[i - 1].ToString()];
if (previousDigit < digit)
{
digit -= previousDigit;
i--;
}
}
total += digit;
}
return total;
}
public static string ToRomanNumeralString(this int value)
{
const int MinValue = 1;
const int MaxValue = 3999;
if ((value < MinValue) || (value > MaxValue))
{
throw new ArgumentOutOfRangeException("value", value, "Argument out of Roman numeral range.");
}
const int MaxRomanNumeralLength = 15;
var sb = new StringBuilder(MaxRomanNumeralLength);
foreach (var pair in romanNumerals)
{
while (value / pair.Value > 0)
{
sb.Append(pair.Key);
value -= pair.Value;
}
}
return sb.ToString();
}
}
从集合中加载默认设置的一种更简单的方法(在现实生活中,我使用它来填充来自任何来源的设置,包括命令行,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" } });