Reputation: 2937
Let's make a list of answers where you post your excellent and favorite extension methods.
The requirement is that the full code must be posted and a example and an explanation on how to use it.
Based on the high interest in this topic I have setup an Open Source Project called extensionoverflow on Codeplex.
Please mark your answers with an acceptance to put the code in the Codeplex project.
Please post the full sourcecode and not a link.
Codeplex News:
24.08.2010 The Codeplex page is now here: http://extensionoverflow.codeplex.com/
11.11.2008 XmlSerialize / XmlDeserialize is now Implemented and Unit Tested.
11.11.2008 There is still room for more developers. ;-) Join NOW!
11.11.2008 Third contributer joined ExtensionOverflow, welcome to BKristensen
11.11.2008 FormatWith is now Implemented and Unit Tested.
09.11.2008 Second contributer joined ExtensionOverflow. welcome to chakrit.
09.11.2008 We need more developers. ;-)
09.11.2008 ThrowIfArgumentIsNull in now Implemented and Unit Tested on Codeplex.
Upvotes: 478
Views: 134906
Reputation: 45095
Another one, this time to make UriBuilder more friendly when dealing with query params.
/// <summary>
/// Adds the specified query parameter to the URI builder.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="parameterName">Name of the parameter.</param>
/// <param name="value">The URI escaped value.</param>
/// <returns>The final full query string.</returns>
public static string AddQueryParam(this UriBuilder builder, string parameterName, string value)
{
if (parameterName == null)
throw new ArgumentNullException("parameterName");
if (parameterName.Length == 0)
throw new ArgumentException("The parameter name is empty.");
if (value == null)
throw new ArgumentNullException("value");
if (value.Length == 0)
throw new ArgumentException("The value is empty.");
if (builder.Query.Length == 0)
{
builder.Query = String.Concat(parameterName, "=", value);
}
else if
(builder.Query.Contains(String.Concat("&", parameterName, "="))
|| builder.Query.Contains(String.Concat("?", parameterName, "=")))
{
throw new InvalidOperationException(String.Format("The parameter {0} already exists.", parameterName));
}
else
{
builder.Query = String.Concat(builder.Query.Substring(1), "&", parameterName, "=", value);
}
return builder.Query;
}
Upvotes: 0
Reputation: 6472
How about ...
public static bool IsWinXPOrHigher(this OperatingSystem OS)
{
return (OS.Platform == PlatformID.Win32NT)
&& ((OS.Version.Major > 5) || ((OS.Version.Major == 5) && (OS.Version.Minor >= 1)));
}
public static bool IsWinVistaOrHigher(this OperatingSystem OS)
{
return (OS.Platform == PlatformID.Win32NT)
&& (OS.Version.Major >= 6);
}
public static bool IsWin7OrHigher(this OperatingSystem OS)
{
return (OS.Platform == PlatformID.Win32NT)
&& ((OS.Version.Major > 6) || ((OS.Version.Major == 6) && (OS.Version.Minor >= 1)));
}
public static bool IsWin8OrHigher(this OperatingSystem OS)
{
return (OS.Platform == PlatformID.Win32NT)
&& ((OS.Version.Major > 6) || ((OS.Version.Major == 6) && (OS.Version.Minor >= 2)));
}
Usage:
if (Environment.OSVersion.IsWinXPOrHigher())
{
// do stuff
}
if (Environment.OSVersion.IsWinVistaOrHigher())
{
// do stuff
}
if (Environment.OSVersion.IsWin7OrHigher())
{
// do stuff
}
if (Environment.OSVersion.IsWin8OrHigher())
{
// do stuff
}
Upvotes: 0
Reputation: 16861
I use the following extensions to extend all collections (maybe someone find these useful):
/// <summary>
/// Collection Helper
/// </summary>
/// <remarks>
/// Use IEnumerable by default, but when altering or getting item at index use IList.
/// </remarks>
public static class CollectionHelper
{
#region Alter;
/// <summary>
/// Swap item to another place
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="IndexA">Index a</param>
/// <param name="IndexB">Index b</param>
/// <returns>New collection</returns>
public static IList<T> Swap<T>(this IList<T> @this, Int32 IndexA, Int32 IndexB)
{
T Temp = @this[IndexA];
@this[IndexA] = @this[IndexB];
@this[IndexB] = Temp;
return @this;
}
/// <summary>
/// Swap item to the left
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index</param>
/// <returns>New collection</returns>
public static IList<T> SwapLeft<T>(this IList<T> @this, Int32 Index)
{
return @this.Swap(Index, Index - 1);
}
/// <summary>
/// Swap item to the right
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index</param>
/// <returns>New collection</returns>
public static IList<T> SwapRight<T>(this IList<T> @this, Int32 Index)
{
return @this.Swap(Index, Index + 1);
}
#endregion Alter;
#region Action;
/// <summary>
/// Execute action at specified index
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index</param>
/// <param name="ActionAt">Action to execute</param>
/// <returns>New collection</returns>
public static IList<T> ActionAt<T>(this IList<T> @this, Int32 Index, Action<T> ActionAt)
{
ActionAt(@this[Index]);
return @this;
}
#endregion Action;
#region Randomize;
/// <summary>
/// Take random items
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Count">Number of items to take</param>
/// <returns>New collection</returns>
public static IEnumerable<T> TakeRandom<T>(this IEnumerable<T> @this, Int32 Count)
{
return @this.Shuffle().Take(Count);
}
/// <summary>
/// Take random item
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <returns>Item</returns>
public static T TakeRandom<T>(this IEnumerable<T> @this)
{
return @this.TakeRandom(1).Single();
}
/// <summary>
/// Shuffle list
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <returns>New collection</returns>
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> @this)
{
return @this.OrderBy(Item => Guid.NewGuid());
}
#endregion Randomize;
#region Navigate;
/// <summary>
/// Get next item in collection and give first item, when last item is selected;
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index in collection</param>
/// <returns>Next item</returns>
public static T Next<T>(this IList<T> @this, ref Int32 Index)
{
Index = ++Index >= 0 && Index < @this.Count ? Index : 0;
return @this[Index];
}
/// <summary>
/// Get previous item in collection and give last item, when first item is selected;
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <param name="Index">Index in collection</param>
/// <returns>Previous item</returns>
public static T Previous<T>(this IList<T> @this, ref Int32 Index)
{
Index = --Index >= 0 && Index < @this.Count ? Index : @this.Count - 1;
return @this[Index];
}
#endregion Navigate;
#region Clone;
/// <summary>
///
/// </summary>
/// <typeparam name="T">Collection type</typeparam>
/// <param name="this">Collection</param>
/// <returns>Cloned collection</returns>
public static IEnumerable<T> Clone<T>(this IEnumerable<T> @this) where T : ICloneable
{
return @this.Select(Item => (T)Item.Clone());
}
#endregion Clone;
#region String;
/// <summary>
/// Joins multiple string with Separator
/// </summary>
/// <param name="this">Collection</param>
/// <param name="Separator">Separator</param>
/// <returns>Joined string</returns>
public static String Join(this IEnumerable<String> @this, String Separator = "")
{
return String.Join(Separator, @this);
}
#endregion String;
}
Upvotes: 0
Reputation: 20157
Here's a to-and-from for Roman numerals. Not often used, but could be handy. Usage:
if ("IV".IsValidRomanNumeral())
{
// Do useful stuff with the number 4.
}
Console.WriteLine("MMMDCCCLXXXVIII".ParseRomanNumeral());
Console.WriteLine(3888.ToRomanNumeralString());
The source:
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();
}
}
Upvotes: 28
Reputation: 18743
Used in winforms to fill a comboBox:
List<MyObject> myObjects = new List<MyObject>() {
new MyObject() {Name = "a", Id = 0},
new MyObject() {Name = "b", Id = 1},
new MyObject() {Name = "c", Id = 2} }
comboBox.FillDataSource<MyObject>(myObjects, x => x.Name);
The extension method:
/** <summary>Fills the System.Windows.Forms.ComboBox object DataSource with a
* list of T objects.</summary>
* <param name="values">The list of T objects.</param>
* <param name="displayedValue">A function to apply to each element to get the
* display value.</param>
*/
public static void FillDataSource<T>(this ComboBox comboBox, List<T> values,
Func<T, String> displayedValue) {
// Create dataTable
DataTable data = new DataTable();
data.Columns.Add("ValueMember", typeof(T));
data.Columns.Add("DisplayMember");
for (int i = 0; i < values.Count; i++) {
// For each value/displayed value
// Create new row with value & displayed value
DataRow dr = data.NewRow();
dr["ValueMember"] = values[i];
dr["DisplayMember"] = displayedValue(values[i]) ?? "";
// Add row to the dataTable
data.Rows.Add(dr);
}
// Bind datasource to the comboBox
comboBox.DataSource = data;
comboBox.ValueMember = "ValueMember";
comboBox.DisplayMember = "DisplayMember";
}
Upvotes: 2
Reputation: 2303
I haven't seen any answer with this one yet...
public static string[] Split(this string value, string regexPattern)
{
return value.Split(regexPattern, RegexOptions.None);
}
public static string[] Split(this string value, string regexPattern,
RegexOptions options)
{
return Regex.Split(value, regexPattern, options);
}
Usage:
var obj = "test1,test2,test3";
string[] arrays = obj.Split(",");
Upvotes: 1
Reputation: 17499
// Checks for an empty collection, and sends the value set in the default constructor for the desired field
public static TResult MinGuarded<T, TResult>(this IEnumerable<T> items, Func<T, TResult> expression) where T : new() {
if(items.IsEmpty()) {
return (new List<T> { new T() }).Min(expression);
}
return items.Min(expression);
}
// Checks for an empty collection, and sends the value set in the default constructor for the desired field
public static TResult MaxGuarded<T, TResult>(this IEnumerable<T> items, Func<T, TResult> expression) where T : new() {
if(items.IsEmpty()) {
return (new List<T> { new T() }).Max(expression);
}
return items.Max(expression);
}
I am not sure if there is a better way to do this, but this extension is very helpful whenever I want to have control over the default values of fields in my object.
For instance, if I want to control the value of a DateTime and want to be set as per my business logic, then I can do so in the default constructor. Otherwise, it comes out to be DateTime.MinDate
.
Upvotes: 0
Reputation: 18743
In .NET, there is a IndexOf
and a LastIndexOf
methods that return the index of the first and the last occurrence of a match in a String
object. I have an extension method to get the index of the nth occurrence:
public static partial class StringExtensions {
public static int NthIndexOf(this String str, String match, int occurrence) {
int i = 1;
int index = 0;
while (i <= occurrence &&
( index = str.IndexOf(match, index + 1) ) != -1) {
if (i == occurrence) {
// Occurrence match found!
return index;
}
i++;
}
// Match not found
return -1;
}
}
Upvotes: 2
Reputation: 771
There is somethimes need to have instance of class no matter if valid but not null
public static T Safe<T>(this T obj) where T : new()
{
if (obj == null)
{
obj = new T();
}
return obj;
}
usage will be like:
MyClass myClass = Provider.GetSomeResult();
string temp = myClass.Safe().SomeValue;
instead of:
MyClass myClass = Provider.GetSomeResult();
string temp = "some default value";
if (myClass != null)
{
temp = myClass.SomeValue;
}
sorry if it is a duplicity, but I dont find it.
Upvotes: 1
Reputation: 771
on serializing and configs there is better using long as DateTime, so:
public static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0);
public static long ToUnixTimestamp(this DateTime dateTime)
{
return (long) (dateTime - Epoch).TotalSeconds;
}
public static long ToUnixUltraTimestamp(this DateTime dateTime)
{
return (long) (dateTime - Epoch).TotalMilliseconds;
}
and backwards
public static DateTime ToDateTime(this long unixDateTime)
{
return Epoch.AddSeconds(unixDateTime);
}
public static DateTime ToDateTimeUltra(this long unixUltraDateTime)
{
return Epoch.AddMilliseconds(unixUltraDateTime);
}
Upvotes: 0
Reputation: 1
If you need for check your string for Is All char is 0 :
static public bool IsAllZero (this string input)
{
if(string.IsNullOrEmpty(input))
return true;
foreach (char ch in input)
{
if(ch != '0')
return false;
}
return true;
}
Upvotes: 0
Reputation: 1
If you have persian language and must show the numbers to users in persian language:
static public string ToFaString (this string value)
{
// 1728 , 1584
string result = "";
if (value != null)
{
char[] resChar = value.ToCharArray();
for (int i = 0; i < resChar.Length; i++)
{
if (resChar[i] >= '0' && resChar[i] <= '9')
result += (char)(resChar[i] + 1728);
else
result += resChar[i];
}
}
return result;
}
Upvotes: 0
Reputation: 16949
Use reflection to find the TryParse method and invoke it upon string target. The optional parameter specifies what should be returned if the conversion fails. I find this method quite useful, most of the time. Well aware of the Convert.ChangeType
option, but I find this more useful what with the default result handy and whatnot. Note that the found methods are kept in a dictionary, although I do suspect that boxing ultimately slows this down a bit.
This method is my favorite, because it legitimately uses a lot of language features.
private static readonly Dictionary<Type, MethodInfo> Parsers = new Dictionary<Type, MethodInfo>();
public static T Parse<T>(this string value, T defaultValue = default(T))
{
if (string.IsNullOrEmpty(value)) return defaultValue;
if (!Parsers.ContainsKey(typeof(T)))
Parsers[typeof (T)] = typeof (T).GetMethods(BindingFlags.Public | BindingFlags.Static)
.Where(mi => mi.Name == "TryParse")
.Single(mi =>
{
var parameters = mi.GetParameters();
if (parameters.Length != 2) return false;
return parameters[0].ParameterType == typeof (string) &&
parameters[1].ParameterType == typeof (T).MakeByRefType();
});
var @params = new object[] {value, default(T)};
return (bool) Parsers[typeof (T)].Invoke(null, @params) ?
(T) @params[1] : defaultValue;
}
Usage:
var hundredTwentyThree = "123".Parse(0);
var badnumber = "test".Parse(-1);
var date = "01/01/01".Parse<DateTime>();
Upvotes: 1
Reputation: 110071
Sql server has a limit of ~2000 parameters, which is a pain if you have 10k Ids and want the records connected with them. I wrote these methods which accept batched lists of ids and are called like this:
List<Order> orders = dataContext.Orders.FetchByIds(
orderIdChunks,
list => row => list.Contains(row.OrderId)
);
List<Customer> customers = dataContext.Orders.FetchByIds(
orderIdChunks,
list => row => list.Contains(row.OrderId),
row => row.Customer
);
public static List<ResultType> FetchByIds<RecordType, ResultType>(
this IQueryable<RecordType> querySource,
List<List<int>> IdChunks,
Func<List<int>, Expression<Func<RecordType, bool>>> filterExpressionGenerator,
Expression<Func<RecordType, ResultType>> projectionExpression
) where RecordType : class
{
List<ResultType> result = new List<ResultType>();
foreach (List<int> chunk in IdChunks)
{
Expression<Func<RecordType, bool>> filterExpression =
filterExpressionGenerator(chunk);
IQueryable<ResultType> query = querySource
.Where(filterExpression)
.Select(projectionExpression);
List<ResultType> rows = query.ToList();
result.AddRange(rows);
}
return result;
}
public static List<RecordType> FetchByIds<RecordType>(
this IQueryable<RecordType> querySource,
List<List<int>> IdChunks,
Func<List<int>, Expression<Func<RecordType, bool>>> filterExpressionGenerator
) where RecordType : class
{
Expression<Func<RecordType, RecordType>> identity = r => r;
return FetchByIds(
querySource,
IdChunks,
filterExpressionGenerator,
identity
);
}
Upvotes: 0
Reputation: 4134
Here's a bitmap extension which can convert bitmaps to grayscale;
public static Bitmap GrayScale(this Bitmap bitmap)
{
Bitmap newBitmap = new Bitmap(bitmap.Width, bitmap.Height);
Graphics g = Graphics.FromImage(newBitmap);
//the grayscale ColorMatrix
ColorMatrix colorMatrix = new ColorMatrix(new float[][] {
new float[] {.3f, .3f, .3f, 0, 0},
new float[] {.59f, .59f, .59f, 0, 0},
new float[] {.11f, .11f, .11f, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});
ImageAttributes attributes = new ImageAttributes();
attributes.SetColorMatrix(colorMatrix);
g.DrawImage(bitmap, new Rectangle(0, 0, bitmap.Width, bitmap.Height), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, attributes);
g.Dispose();
return newBitmap;
}
Sample usage:
Bitmap grayscaled = bitmap.GrayScale()
Upvotes: 5
Reputation: 71565
Here's another pair I've found endless use for:
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;
}
Usage:
var myObject = myList.ObjectWithMin(x=>x.PropA);
These methods basically replace usages like
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)
Upvotes: 5
Reputation: 18315
One of my favorites is an IsLike() extension on String. IsLike() matches VB's Like operator, and is handy when you don't want to write a full-on regex to solve your problem. Usage would be something like this:
"abc".IsLike("a*"); // true
"Abc".IsLike("[A-Z][a-z][a-z]"); // true
"abc123".IsLike("*###"); // true
"hat".IsLike("?at"); // true
"joe".IsLike("[!aeiou]*"); // true
"joe".IsLike("?at"); // false
"joe".IsLike("[A-Z][a-z][a-z]"); // false
Here's the code
public static class StringEntentions {
/// <summary>
/// Indicates whether the current string matches the supplied wildcard pattern. Behaves the same
/// as VB's "Like" Operator.
/// </summary>
/// <param name="s">The string instance where the extension method is called</param>
/// <param name="wildcardPattern">The wildcard pattern to match. Syntax matches VB's Like operator.</param>
/// <returns>true if the string matches the supplied pattern, false otherwise.</returns>
/// <remarks>See http://msdn.microsoft.com/en-us/library/swf8kaxw(v=VS.100).aspx</remarks>
public static bool IsLike(this string s, string wildcardPattern) {
if (s == null || String.IsNullOrEmpty(wildcardPattern)) return false;
// turn into regex pattern, and match the whole string with ^$
var regexPattern = "^" + Regex.Escape(wildcardPattern) + "$";
// add support for ?, #, *, [], and [!]
regexPattern = regexPattern.Replace(@"\[!", "[^")
.Replace(@"\[", "[")
.Replace(@"\]", "]")
.Replace(@"\?", ".")
.Replace(@"\*", ".*")
.Replace(@"\#", @"\d");
var result = false;
try {
result = Regex.IsMatch(s, regexPattern);
}
catch (ArgumentException ex) {
throw new ArgumentException(String.Format("Invalid pattern: {0}", wildcardPattern), ex);
}
return result;
}
}
Upvotes: 11
Reputation: 38333
Some Date functions:
public static bool IsFuture(this DateTime date, DateTime from)
{
return date.Date > from.Date;
}
public static bool IsFuture(this DateTime date)
{
return date.IsFuture(DateTime.Now);
}
public static bool IsPast(this DateTime date, DateTime from)
{
return date.Date < from.Date;
}
public static bool IsPast(this DateTime date)
{
return date.IsPast(DateTime.Now);
}
Upvotes: 7
Reputation: 7794
Would be great to have Unix TimeStamp and ISO 8601 formatted date and times. heavily used in websites and rest services.
I use it in my Facebook Library. You can find the source http://github.com/prabirshrestha/FacebookSharp/blob/master/src/FacebookSharp.Core/FacebookUtils/DateUtils.cs
private static readonly DateTime EPOCH = DateTime.SpecifyKind(new DateTime(1970, 1, 1, 0, 0, 0, 0),DateTimeKind.Utc);
public static DateTime FromUnixTimestamp(long timestamp)
{
return EPOCH.AddSeconds(timestamp);
}
public static long ToUnixTimestamp(DateTime date)
{
TimeSpan diff = date.ToUniversalTime() - EPOCH;
return (long)diff.TotalSeconds;
}
public static DateTime FromIso8601FormattedDateTime(string iso8601DateTime){
return DateTime.ParseExact(iso8601DateTime, "o", System.Globalization.CultureInfo.InvariantCulture);
}
public static string ToIso8601FormattedDateTime(DateTime dateTime)
{
return dateTime.ToString("o");
}
Feel free to use in the codeplex project.
Upvotes: 3
Reputation: 40223
Similar to the string As and Is above, but global to all objects.
It's quite simple, but I use these a lot to alleviate parens explosion with boxing.
public static class ExtensionMethods_Object
{
[DebuggerStepThrough()]
public static bool Is<T>(this object item) where T : class
{
return item is T;
}
[DebuggerStepThrough()]
public static bool IsNot<T>(this object item) where T : class
{
return !(item.Is<T>());
}
[DebuggerStepThrough()]
public static T As<T>(this object item) where T : class
{
return item as T;
}
}
I am happy for this code to be used at codeplex, indeed it already is.
Upvotes: 10
Reputation: 292345
I find the following extension method quite useful:
public static T GetService<T>(this IServiceProvider provider)
{
return (T)provider.GetService(typeof(T));
}
It makes it much easier to use the IServiceProvider
interface. Compare:
IProvideValueTarget target = (IProvideValueTarget)serviceProvider(typeof(IProvideValueTarget));
and
var target = serviceProvider.GetService<IProvideValueTarget>();
Upvotes: 4
Reputation: 42497
String.As<T>
, which can be used to convert a string value as some type (intended to be used primarily with primitives and types that support IConvertable. Works great with Nullable
types and even Enums!
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;
}
}
This relies on another simple extension for 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<>));
}
}
Usage:
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
Upvotes: 4
Reputation:
public static class StringHelper
{
public static String F(this String str, params object[] args)
{
return String.Format(str, args);
}
}
Using like:
"Say {0}".F("Hello");
Upvotes: 0
Reputation: 18491
While working with MVC and having lots of if
statements where i only care about either true
or false
, and printing null
, or string.Empty
in the other case, I came up with:
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);
}
It allows me to change <%= (someBool) ? "print y" : string.Empty %>
into <%= someBool.WhenTrue("print y") %>
.
I only use it in my Views where I mix code and HTML, in code files writing the "longer" version is more clear IMHO.
Upvotes: 3
Reputation: 11535
Some handy string helpers:
Usage:
I hate unwanted spaces trailing or leading strings and since string can take on a null
value, it can be tricky, so i use this:
public bool IsGroup { get { return !this.GroupName.IsNullOrTrimEmpty(); } }
Here is another extention method that i use for a new validation framework i'm trialing. You can see the regex extensions within that help clean otherwise messy regex:
public static bool IsRequiredWithLengthLessThanOrEqualNoSpecial(this String str, int length)
{
return !str.IsNullOrTrimEmpty() &&
str.RegexMatch(
@"^[- \r\n\\\.!:*,@$%&""?\(\)\w']{1,{0}}$".RegexReplace(@"\{0\}", length.ToString()),
RegexOptions.Multiline) == str;
}
Source:
public static class StringHelpers
{
/// <summary>
/// Same as String.IsNullOrEmpty except that
/// it captures the Empty state for whitespace
/// strings by Trimming first.
/// </summary>
public static bool IsNullOrTrimEmpty(this String helper)
{
if (helper == null)
return true;
else
return String.Empty == helper.Trim();
}
public static int TrimLength(this String helper)
{
return helper.Trim().Length;
}
/// <summary>
/// Returns the matched string from the regex pattern. The
/// groupName is for named group match values in the form (?<name>group).
/// </summary>
public static string RegexMatch(this String helper, string pattern, RegexOptions options, string groupName)
{
if (groupName.IsNullOrTrimEmpty())
return Regex.Match(helper, pattern, options).Value;
else
return Regex.Match(helper, pattern, options).Groups[groupName].Value;
}
public static string RegexMatch(this String helper, string pattern)
{
return RegexMatch(helper, pattern, RegexOptions.None, null);
}
public static string RegexMatch(this String helper, string pattern, RegexOptions options)
{
return RegexMatch(helper, pattern, options, null);
}
public static string RegexMatch(this String helper, string pattern, string groupName)
{
return RegexMatch(helper, pattern, RegexOptions.None, groupName);
}
/// <summary>
/// Returns true if there is a match from the regex pattern
/// </summary>
public static bool IsRegexMatch(this String helper, string pattern, RegexOptions options)
{
return helper.RegexMatch(pattern, options).Length > 0;
}
public static bool IsRegexMatch(this String helper, string pattern)
{
return helper.IsRegexMatch(pattern, RegexOptions.None);
}
/// <summary>
/// Returns a string where matching patterns are replaced by the replacement string.
/// </summary>
/// <param name="pattern">The regex pattern for matching the items to be replaced</param>
/// <param name="replacement">The string to replace matching items</param>
/// <returns></returns>
public static string RegexReplace(this String helper, string pattern, string replacement, RegexOptions options)
{
return Regex.Replace(helper, pattern, replacement, options);
}
public static string RegexReplace(this String helper, string pattern, string replacement)
{
return Regex.Replace(helper, pattern, replacement, RegexOptions.None);
}
}
I like to do a lot of regex so i consider these easier than adding the using statement and the extra code to handle named groups.
Upvotes: 1
Reputation: 8037
Wraps a string every n chars.
public static string WrapAt(this string str, int WrapPos)
{
if (string.IsNullOrEmpty(str))
throw new ArgumentNullException("str", "Cannot wrap a null string");
str = str.Replace("\r", "").Replace("\n", "");
if (str.Length <= WrapPos)
return str;
for (int i = str.Length; i >= 0; i--)
if (i % WrapPos == 0 && i > 0 && i != str.Length)
str = str.Insert(i, "\r\n");
return str;
}
Upvotes: 2
Reputation: 8037
In the recent searches section on my blog stats page, I had removed all duplicates, but needed a way to remove nearly-duplicate lines. I'd get tons of similar but not quite the same Google queries.
I ended up using an anonymous type instead of a dictionary, but wanted a way to create a List of that anonymous type. You can't do that, but you can create a List<dynamic>
in .NET 4.0 :)
Mostly I like it because I effectively get a List<AnonymousType#1>()
.
/// <summary>Remove extraneous entries for common word permutations</summary>
/// <param name="input">Incoming series of words to be filtered</param>
/// <param name="MaxIgnoreLength">Words this long or shorter will not count as duplicates</param>
/// <param name="words2">Instance list from BuildInstanceList()</param>
/// <returns>Filtered list of lines from input, based on filter info in words2</returns>
private static List<string> FilterNearDuplicates(List<string> input, int MaxIgnoreLength, List<dynamic> words2)
{
List<string> output = new List<string>();
foreach (string line in input)
{
int Dupes = 0;
foreach (string word in line.Split(new char[] { ' ', ',', ';', '\\', '/', ':', '\"', '\r', '\n', '.' })
.Where(p => p.Length > MaxIgnoreLength)
.Distinct())
{
int Instances = 0;
foreach (dynamic dyn in words2)
if (word == dyn.Word)
{
Instances = dyn.Instances;
if (Instances > 1)
Dupes++;
break;
}
}
if (Dupes == 0)
output.Add(line);
}
return output;
}
/// <summary>Builds a list of words and how many times they occur in the overall list</summary>
/// <param name="input">Incoming series of words to be counted</param>
/// <returns></returns>
private static List<dynamic> BuildInstanceList(List<string> input)
{
List<dynamic> words2 = new List<object>();
foreach (string line in input)
foreach (string word in line.Split(new char[] { ' ', ',', ';', '\\', '/', ':', '\"', '\r', '\n', '.' }))
{
if (string.IsNullOrEmpty(word))
continue;
else if (ExistsInList(word, words2))
for (int i = words2.Count - 1; i >= 0; i--)
{
if (words2[i].Word == word)
words2[i] = new { Word = words2[i].Word, Instances = words2[i].Instances + 1 };
}
else
words2.Add(new { Word = word, Instances = 1 });
}
return words2;
}
/// <summary>Determines whether a dynamic Word object exists in a List of this dynamic type.</summary>
/// <param name="word">Word to look for</param>
/// <param name="words">Word dynamics to search through</param>
/// <returns>Indicator of whether the word exists in the list of words</returns>
private static bool ExistsInList(string word, List<dynamic> words)
{
foreach (dynamic dyn in words)
if (dyn.Word == word)
return true;
return false;
}
Upvotes: 0
Reputation: 1771
I found this one helpful
public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> pSeq)
{
return pSeq ?? Enumerable.Empty<T>();
}
It removes the null check in the calling code. You could now do
MyList.EmptyIfNull().Where(....)
Upvotes: 17
Reputation:
I use this extension method usually with anonymous types to get a dictionary ala ruby
public static Dictionary<string, object> ToDictionary(this object o)
{
var dictionary = new Dictionary<string, object>();
foreach (var propertyInfo in o.GetType().GetProperties())
{
if (propertyInfo.GetIndexParameters().Length == 0)
{
dictionary.Add(propertyInfo.Name, propertyInfo.GetValue(o, null));
}
}
return dictionary;
}
You can use it
var dummy = new { color = "#000000", width = "100%", id = "myid" };
Dictionary<string, object> dict = dummy.ToDictionary();
And with an extended method as
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
foreach (T item in source)
{
action(item);
}
}
You can do it
dummy.ToDictionary().ForEach((p) => Console.Write("{0}='{1}' ", p.Key, p.Value));
Output
color='#000000' width='100%' id='myid'
Upvotes: 6
Reputation: 1531
Equivalent to Python's Join method:
/// <summary>
/// same as python 'join'
/// </summary>
/// <typeparam name="T">list type</typeparam>
/// <param name="separator">string separator </param>
/// <param name="list">list of objects to be ToString'd</param>
/// <returns>a concatenated list interleaved with separators</returns>
static public string Join<T>(this string separator, IEnumerable<T> list)
{
var sb = new StringBuilder();
bool first = true;
foreach (T v in list)
{
if (!first)
sb.Append(separator);
first = false;
if (v != null)
sb.Append(v.ToString());
}
return sb.ToString();
}
Upvotes: 1