Skip to content

Commit 6900055

Browse files
committed
Added extension methods from old FCL.
1 parent 7f7ba29 commit 6900055

File tree

10 files changed

+565
-0
lines changed

10 files changed

+565
-0
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Whathecode.System.Arithmetic.Range;
2+
3+
4+
namespace Whathecode.System.Extensions
5+
{
6+
public static partial class Extensions
7+
{
8+
/// <summary>
9+
/// Returns the interval of the indices.
10+
/// </summary>
11+
/// <typeparam name = "T">Type of the values in the array.</typeparam>
12+
/// <param name = "source">The source for this extension method.</param>
13+
/// <returns>The interval of the indices of the array.</returns>
14+
public static Interval<int> GetIndexInterval<T>( this T[] source )
15+
{
16+
return new Interval<int>( 0, source.Length - 1 );
17+
}
18+
}
19+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
using System;
2+
3+
4+
namespace Whathecode.System.Extensions
5+
{
6+
public static partial class Extensions
7+
{
8+
/// <summary>
9+
/// Returns part of the <see cref="DateTime" /> object.
10+
/// </summary>
11+
/// <param name = "source">The <see cref="DateTime" /> to retrieve a part from.</param>
12+
/// <param name = "part">Which part of the <see cref="DateTime" /> to retrieve.</param>
13+
public static double GetDateTimePart( this DateTime source, DateTimePart part )
14+
{
15+
switch ( part )
16+
{
17+
case DateTimePart.Day:
18+
return source.Day;
19+
case DateTimePart.Hour:
20+
return source.Hour;
21+
case DateTimePart.Millisecond:
22+
return source.Millisecond;
23+
case DateTimePart.Minute:
24+
return source.Minute;
25+
case DateTimePart.Month:
26+
return source.Month;
27+
case DateTimePart.Second:
28+
return source.Second;
29+
case DateTimePart.Year:
30+
return source.Year;
31+
}
32+
33+
throw new NotSupportedException();
34+
}
35+
36+
/// <summary>
37+
/// Returns a new <see cref="DateTime" /> object which is rounded down to the specified <paramref name="part" />.
38+
/// </summary>
39+
/// <param name = "source">The <see cref="DateTime" /> to round down.</param>
40+
/// <param name = "part">The part to round down to.</param>
41+
public static DateTime Round( this DateTime source, DateTimePart part )
42+
{
43+
return new DateTime(
44+
source.Year,
45+
part >= DateTimePart.Month ? source.Month : 1,
46+
part >= DateTimePart.Day ? source.Day : 1,
47+
part >= DateTimePart.Hour ? source.Hour : 0,
48+
part >= DateTimePart.Minute ? source.Minute : 0,
49+
part >= DateTimePart.Second ? source.Second : 0,
50+
part >= DateTimePart.Millisecond ? source.Millisecond : 0 );
51+
}
52+
53+
/// <summary>
54+
/// Returns a new <see cref="DateTime" /> object which is rounded down to the day indicating the start of the week.
55+
/// </summary>
56+
/// <param name = "source">The <see cref="DateTime" /> to round down.</param>
57+
/// <param name = "startOfWeek">They day of the week to round down to.</param>
58+
public static DateTime Round( this DateTime source, DayOfWeek startOfWeek )
59+
{
60+
int excessDays = source.DayOfWeek - startOfWeek;
61+
if ( excessDays < 0 )
62+
{
63+
excessDays += 7;
64+
}
65+
66+
return source.Date - TimeSpan.FromDays( excessDays );
67+
}
68+
69+
/// <summary>
70+
/// Safely subtract a given timespan from a <see cref="DateTime" />, preventing an <see cref="ArgumentOutOfRangeException" /> from occurring.
71+
/// When the subtraction results in an invalid <see cref="DateTime" />, the nearest valid <see cref="DateTime" /> is used.
72+
/// </summary>
73+
/// <param name = "source">The <see cref="DateTime" /> to subtract from.</param>
74+
/// <param name = "time">The amount of time to subtract from the <see cref="DateTime" />.</param>
75+
public static DateTime SafeSubtract( this DateTime source, TimeSpan time )
76+
{
77+
long minTicks = DateTime.MinValue.Ticks;
78+
79+
return source.Ticks - time.Ticks < minTicks
80+
? DateTime.MinValue
81+
: source - time;
82+
}
83+
84+
/// <summary>
85+
/// Safely add a given timespan to a <see cref="DateTime" />, preventing an <see cref="ArgumentOutOfRangeException" /> from occurring.
86+
/// When the addition results in an invalid <see cref="DateTime" />, the nearest valid <see cref="DateTime" /> is used.
87+
/// </summary>
88+
/// <param name = "source">The <see cref="DateTime" /> to add to.</param>
89+
/// <param name = "time">The amount of time to add to the <see cref="DateTime" />.</param>
90+
public static DateTime SafeAdd( this DateTime source, TimeSpan time )
91+
{
92+
long maxTicks = DateTime.MaxValue.Ticks;
93+
94+
return source.Ticks + time.Ticks > maxTicks
95+
? DateTime.MaxValue
96+
: source + time;
97+
}
98+
}
99+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
5+
namespace Whathecode.System.Extensions
6+
{
7+
public static partial class Extensions
8+
{
9+
/// <summary>
10+
/// Gets the value associated with the specified key and passes it to delegate which can use it.
11+
/// </summary>
12+
/// <typeparam name = "TKey">The type of the keys in the dictionary.</typeparam>
13+
/// <typeparam name = "TValue">The type of the values in the dictionary.</typeparam>
14+
/// <param name = "source">The source for this extension method.</param>
15+
/// <param name = "key">The key of the element to use the value of if it's contained within the dictionary.</param>
16+
/// <param name = "useValue">The action to perform with the value if the key is contained within the dictionary.</param>
17+
/// <returns>true when the key was present in the dictionary and the action was performed, false otherwise.</returns>
18+
public static bool TryUseValue<TKey, TValue>( this Dictionary<TKey, TValue> source, TKey key, Action<TValue> useValue )
19+
{
20+
TValue value;
21+
if ( source.TryGetValue( key, out value ) )
22+
{
23+
useValue( value );
24+
25+
return true;
26+
}
27+
28+
return false;
29+
}
30+
31+
/// <summary>
32+
/// Adds/updates or removes a certain key from the dictionary. The key is removed when the value is null.
33+
/// </summary>
34+
/// <typeparam name = "TKey">The type of the keys in the dictionary.</typeparam>
35+
/// <typeparam name = "TValue">The type of the values in the dictionary.</typeparam>
36+
/// <param name = "source">The source for this extension method.</param>
37+
/// <param name = "key">The key of the element in the dictionary to update.</param>
38+
/// <param name = "value">The new value for the key.</param>
39+
public static void Update<TKey, TValue>( this Dictionary<TKey, TValue> source, TKey key, TValue value )
40+
where TValue : class
41+
{
42+
if ( source == null || key == null )
43+
{
44+
throw new ArgumentNullException( "Both source and key should be different from null." );
45+
}
46+
47+
source.Update( key, value, v => v != null );
48+
}
49+
50+
/// <summary>
51+
/// Adds/updates or removes a certain key from the dictionary.
52+
/// </summary>
53+
/// <typeparam name = "TKey">The type of the keys in the dictionary.</typeparam>
54+
/// <typeparam name = "TValue">The type of the values in the dictionary.</typeparam>
55+
/// <param name = "source">The source for this extension method.</param>
56+
/// <param name = "key">The key of the element in the dictionary to update.</param>
57+
/// <param name = "value">The new value for the key.</param>
58+
/// <param name = "validValue">
59+
/// Determines whether or not the new value is a valid value. When it returns true the key is updated with the new value,
60+
/// otherwise the key is removed from the dictionary.
61+
/// </param>
62+
public static void Update<TKey, TValue>( this Dictionary<TKey, TValue> source, TKey key, TValue value, Func<TValue, bool> validValue )
63+
{
64+
if ( source == null || key == null || validValue == null )
65+
{
66+
throw new ArgumentNullException( "Both source, key, and validValue should be different from null." );
67+
}
68+
69+
if ( validValue( value ) )
70+
{
71+
source[ key ] = value;
72+
}
73+
else
74+
{
75+
source.Remove( key );
76+
}
77+
}
78+
}
79+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text.RegularExpressions;
6+
7+
8+
namespace Whathecode.System.Extensions
9+
{
10+
public static partial class Extensions
11+
{
12+
/// <summary>
13+
/// Returns an enumerable collection of file information that matches a regular expression.
14+
/// </summary>
15+
/// <param name = "directory">The directory to search in.</param>
16+
/// <param name = "searchOption">Specifies whether to search in all subdirectories as well.</param>
17+
/// <param name = "regexPattern">The regular expression which is used to see whether a file matches.</param>
18+
/// <param name = "regexOptions">Options for the regular expression.</param>
19+
public static IEnumerable<FileInfo> EnumerateFiles(
20+
this DirectoryInfo directory,
21+
SearchOption searchOption,
22+
string regexPattern,
23+
RegexOptions regexOptions = RegexOptions.None )
24+
{
25+
return directory.EnumerateFiles( "*", searchOption ).Where( file => Regex.IsMatch( file.FullName, regexPattern, regexOptions ) );
26+
}
27+
28+
29+
/// <summary>
30+
/// Returns the first common subdirectory if any, null otherwise.
31+
/// </summary>
32+
/// <param name = "source">The source for this extension method.</param>
33+
/// <param name = "directory">The directory to check for a common subdirectory.</param>
34+
/// <returns>The first common subdirectory if any, null otherwise.</returns>
35+
public static DirectoryInfo GetCommonParentDirectory( this DirectoryInfo source, DirectoryInfo directory )
36+
{
37+
Func<DirectoryInfo, Stack<DirectoryInfo>> getParentDirs = d =>
38+
{
39+
Stack<DirectoryInfo> sourceParents = new Stack<DirectoryInfo>();
40+
while ( d.Parent != null )
41+
{
42+
sourceParents.Push( d );
43+
d = d.Parent;
44+
}
45+
sourceParents.Push( d );
46+
return sourceParents;
47+
};
48+
49+
Stack<DirectoryInfo> parents1 = getParentDirs( source );
50+
Stack<DirectoryInfo> parents2 = getParentDirs( directory );
51+
52+
DirectoryInfo lastMatching = null;
53+
while ( parents1.Count > 0 && parents2.Count > 0 )
54+
{
55+
DirectoryInfo p1 = parents1.Pop();
56+
DirectoryInfo p2 = parents2.Pop();
57+
if ( p1.FullName == p2.FullName )
58+
{
59+
lastMatching = p1;
60+
}
61+
else
62+
{
63+
break;
64+
}
65+
}
66+
67+
return lastMatching;
68+
}
69+
}
70+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
using System;
2+
3+
4+
namespace Whathecode.System.Extensions
5+
{
6+
public static partial class Extensions
7+
{
8+
/// <summary>
9+
/// Limit a value to a certain range. When the value is smaller/bigger than the range, snap it to the range border.
10+
/// </summary>
11+
/// <typeparam name = "T">The type of the value to limit.</typeparam>
12+
/// <param name = "source">The source for this extension method.</param>
13+
/// <param name = "start">The start of the interval, included in the interval.</param>
14+
/// <param name = "end">The end of the interval, included in the interval.</param>
15+
/// <returns></returns>
16+
public static T Clamp<T>( this T source, T start, T end )
17+
where T : IComparable
18+
{
19+
bool isReversed = start.CompareTo( end ) > 0;
20+
T smallest = isReversed ? end : start;
21+
T biggest = isReversed ? start : end;
22+
23+
return source.CompareTo( smallest ) < 0
24+
? smallest
25+
: source.CompareTo( biggest ) > 0
26+
? biggest
27+
: source;
28+
}
29+
}
30+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
3+
4+
namespace Whathecode.System.Extensions
5+
{
6+
public static partial class Extensions
7+
{
8+
/// <summary>
9+
/// Returns a new <see cref="TimeSpan" /> object which is rounded down to the specified <paramref name="part" />.
10+
/// </summary>
11+
/// <param name = "source">The <see cref="TimeSpan" /> to round down.</param>
12+
/// <param name = "part">The part to round down to.</param>
13+
public static TimeSpan Round( this TimeSpan source, TimeSpanPart part )
14+
{
15+
return new TimeSpan(
16+
part >= TimeSpanPart.Day ? source.Days : 0,
17+
part >= TimeSpanPart.Hour ? source.Hours : 0,
18+
part >= TimeSpanPart.Minute ? source.Minutes : 0,
19+
part >= TimeSpanPart.Second ? source.Seconds : 0,
20+
part >= TimeSpanPart.Millisecond ? source.Milliseconds : 0 );
21+
}
22+
}
23+
}

0 commit comments

Comments
 (0)