让我们把你的优秀和最喜欢的扩展方法列一个列表。
要求是必须发布完整的代码,以及如何使用它的示例和解释。
基于对这个主题的高度兴趣,我在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上实现和单元测试。
字符串。As<T>,可用于将字符串值转换为某种类型(主要用于支持IConvertable的原语和类型)。工作伟大的空类型,甚至枚举!
public static partial class StringExtensions
{
/// <summary>
/// Converts the string to the specified type, using the default value configured for the type.
/// </summary>
/// <typeparam name="T">Type the string will be converted to. The type must implement IConvertable.</typeparam>
/// <param name="original">The original string.</param>
/// <returns>The converted value.</returns>
public static T As<T>(this String original)
{
return As(original, CultureInfo.CurrentCulture,
default(T));
}
/// <summary>
/// Converts the string to the specified type, using the default value configured for the type.
/// </summary>
/// <typeparam name="T">Type the string will be converted to.</typeparam>
/// <param name="original">The original string.</param>
/// <param name="defaultValue">The default value to use in case the original string is null or empty, or can't be converted.</param>
/// <returns>The converted value.</returns>
public static T As<T>(this String original, T defaultValue)
{
return As(original, CultureInfo.CurrentCulture, defaultValue);
}
/// <summary>
/// Converts the string to the specified type, using the default value configured for the type.
/// </summary>
/// <typeparam name="T">Type the string will be converted to.</typeparam>
/// <param name="original">The original string.</param>
/// <param name="provider">Format provider used during the type conversion.</param>
/// <returns>The converted value.</returns>
public static T As<T>(this String original, IFormatProvider provider)
{
return As(original, provider, default(T));
}
/// <summary>
/// Converts the string to the specified type.
/// </summary>
/// <typeparam name="T">Type the string will be converted to.</typeparam>
/// <param name="original">The original string.</param>
/// <param name="provider">Format provider used during the type conversion.</param>
/// <param name="defaultValue">The default value to use in case the original string is null or empty, or can't be converted.</param>
/// <returns>The converted value.</returns>
/// <remarks>
/// If an error occurs while converting the specified value to the requested type, the exception is caught and the default is returned. It is strongly recommended you
/// do NOT use this method if it is important that conversion failures are not swallowed up.
///
/// This method is intended to be used to convert string values to primatives, not for parsing, converting, or deserializing complex types.
/// </remarks>
public static T As<T>(this String original, IFormatProvider provider,
T defaultValue)
{
T result;
Type type = typeof (T);
if (String.IsNullOrEmpty(original)) result = defaultValue;
else
{
// need to get the underlying type if T is Nullable<>.
if (type.IsNullableType())
{
type = Nullable.GetUnderlyingType(type);
}
try
{
// ChangeType doesn't work properly on Enums
result = type.IsEnum
? (T) Enum.Parse(type, original, true)
: (T) Convert.ChangeType(original, type, provider);
}
catch // HACK: what can we do to minimize or avoid raising exceptions as part of normal operation? custom string parsing (regex?) for well-known types? it would be best to know if you can convert to the desired type before you attempt to do so.
{
result = defaultValue;
}
}
return result;
}
}
这依赖于Type的另一个简单扩展:
/// <summary>
/// Extension methods for <see cref="Type"/>.
/// </summary>
public static class TypeExtensions
{
/// <summary>
/// Returns whether or not the specified type is <see cref="Nullable{T}"/>.
/// </summary>
/// <param name="type">A <see cref="Type"/>.</param>
/// <returns>True if the specified type is <see cref="Nullable{T}"/>; otherwise, false.</returns>
/// <remarks>Use <see cref="Nullable.GetUnderlyingType"/> to access the underlying type.</remarks>
public static bool IsNullableType(this Type type)
{
if (type == null) throw new ArgumentNullException("type");
return type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof (Nullable<>));
}
}
用法:
var someInt = "1".As<int>();
var someIntDefault = "bad value".As(1); // "bad value" won't convert, so the default value 1 is returned.
var someEnum = "Sunday".As<DayOfWeek>();
someEnum = "0".As<DayOfWeek>(); // returns Sunday
var someNullableEnum = "".As<DayOfWeek?>(null); // returns a null value since "" can't be converted
我创建了一个漂亮的Each扩展,具有与jQuery的Each函数相同的行为。
它允许如下所示,你可以获得当前值的索引,并通过返回false跳出循环:
new[] { "first", "second", "third" }.Each((value, index) =>
{
if (value.Contains("d"))
return false;
Console.Write(value);
return true;
});
下面是代码
/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion. A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value in the sequence.
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Action<T> action)
{
return source.Each((value, index) =>
{
action(value);
return true;
});
}
/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion. A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value and its index in the sequence.
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Action<T, int> action)
{
return source.Each((value, index) =>
{
action(value, index);
return true;
});
}
/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion. A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value in the sequence. Returns a value indicating whether the iteration should continue. So return false if you don't want to iterate anymore.</param>
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Func<T, bool> action)
{
return source.Each((value, index) =>
{
return action(value);
});
}
/// <summary>
/// Generic iterator function that is useful to replace a foreach loop with at your discretion. A provided action is performed on each element.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="action">Function that takes in the current value and its index in the sequence. Returns a value indicating whether the iteration should continue. So return false if you don't want to iterate anymore.</param>
/// <returns></returns>
public static IEnumerable<T> Each<T>(this IEnumerable<T> source, Func<T, int, bool> action)
{
if (source == null)
return source;
int index = 0;
foreach (var sourceItem in source)
{
if (!action(sourceItem, index))
break;
index++;
}
return source;
}
我一直在用这个:
public static void DelimitedAppend(this StringBuilder sb, string value, string delimiter)
{
if (sb.Length > 0)
sb.Append(delimiter);
sb.Append(value);
}
这只是确保当字符串为空时不会插入分隔符。
例如,创建一个以逗号分隔的单词列表:
var farmAnimals = new[] { new { Species = "Dog", IsTasty = false }, new { Species = "Cat", IsTasty = false }, new { Species = "Chicken", IsTasty = true }, };
var soupIngredients = new StringBuilder();
foreach (var edible in farmAnimals.Where(farmAnimal => farmAnimal.IsTasty))
soupIngredients.DelimitedAppend(edible.Species, ", ");