1616using System . Collections ;
1717using System . Collections . Generic ;
1818using System . ComponentModel ;
19+ using System . Diagnostics . CodeAnalysis ;
1920using System . Reflection ;
2021using System . Text ;
2122using System . Threading ;
@@ -40,32 +41,31 @@ public static class ObjectExtensions
4041 private const string ObjectPropertyAssignment = " = " ;
4142
4243 /// <summary>
43- /// Determines whether the current <see cref="IComparable {T}"/> value falls within range, inclusive of the specified minimum and maximum values .
44+ /// Calls the specified <see cref="Action {T}"/> with the current <paramref name="value"/> .
4445 /// </summary>
45- /// <param name="value">The value to test .</param>
46- /// <param name="min ">The inclusive minimum value.</param>
47- /// <param name="max ">The inclusive maximum value.</param >
48- /// <typeparam name="T">The underlying <see cref="IComparable {T}"/> type .</typeparam >
49- /// <returns>
50- /// Returns <see langword="true"/> if the current <see cref="IComparable{T}"/> value falls within range,
51- /// inclusive of the specified minimum and maximum values; otherwise, <see langword="false"/>.
52- /// </returns>
53- public static bool IsWithinRangeInclusive < T > ( this T value , T min , T max ) where T : IComparable < T > =>
54- value . CompareTo ( min ) is 0 or 1 && value . CompareTo ( max ) is 0 or - 1 ;
46+ /// <param name="value">The value to pass to the specified <see cref="Action{T}"/> .</param>
47+ /// <param name="action ">The action into which the current <paramref name=" value"/> will be passed .</param>
48+ /// <typeparam name="T ">The underlying type of the current value.</typeparam >
49+ /// <returns>Returns the current <paramref name="value"/> once the specified <see cref="Action {T}"/> has been executed .</returns >
50+ public static T Apply < T > ( this T value , Action < T > action ) where T : class
51+ {
52+ RequireNotNull ( action , "Action must not be null." , nameof ( action ) ) ;
53+ action ( value ) ;
54+ return value ;
55+ }
5556
5657 /// <summary>
57- /// Determines whether the current <see cref="IComparable{T }"/> value falls within range, exclusive of the specified minimum and maximum values .
58+ /// Calls the specified <see cref="Func{T, TResult }"/> with the current <paramref name="value"/> .
5859 /// </summary>
59- /// <param name="value">The value to test.</param>
60- /// <param name="min">The exclusive minimum value.</param>
61- /// <param name="max">The exclusive maximum value.</param>
62- /// <typeparam name="T">The underlying <see cref="IComparable{T}"/> type.</typeparam>
63- /// <returns>
64- /// Returns <see langword="true"/> if the current <see cref="IComparable{T}"/> value falls within range,
65- /// exclusive of the specified minimum and maximum values; otherwise, <see langword="false"/>.
66- /// </returns>
67- public static bool IsWithinRangeExclusive < T > ( this T value , T min , T max ) where T : IComparable < T > =>
68- value . CompareTo ( min ) is 1 && value . CompareTo ( max ) is - 1 ;
60+ /// <param name="value">The value to pass to the specified <see cref="Func{T, TResult}"/>.</param>
61+ /// <param name="function">The function into which the current <paramref name="value"/> will be passed.</param>
62+ /// <typeparam name="T">The underlying type of the current value.</typeparam>
63+ /// <returns>Returns the result of the specified <see cref="Func{T, TResult}"/>.</returns>
64+ public static T Apply < T > ( this T value , Func < T , T > function ) where T : struct
65+ {
66+ RequireNotNull ( function , "Function must not be null." , nameof ( function ) ) ;
67+ return function ( value ) ;
68+ }
6969
7070 /// <summary>
7171 /// Compares the current <typeparamref name="T"/> instance with the specified <typeparamref name="T"/> instance.
@@ -107,6 +107,48 @@ public static int CompareToNullable<T>(this T left, T? right) where T : struct,
107107 _ => throw new ArgumentException ( $ "Object must be of type { typeof ( T ) . FullName } ", nameof ( right ) )
108108 } ;
109109
110+ /// <summary>
111+ /// Determines whether the current <see cref="IComparable{T}"/> value falls within range, inclusive of the specified minimum and maximum values.
112+ /// </summary>
113+ /// <param name="value">The value to test.</param>
114+ /// <param name="min">The inclusive minimum value.</param>
115+ /// <param name="max">The inclusive maximum value.</param>
116+ /// <typeparam name="T">The underlying <see cref="IComparable{T}"/> type.</typeparam>
117+ /// <returns>
118+ /// Returns <see langword="true"/> if the current <see cref="IComparable{T}"/> value falls within range,
119+ /// inclusive of the specified minimum and maximum values; otherwise, <see langword="false"/>.
120+ /// </returns>
121+ public static bool IsWithinRangeInclusive < T > ( this T value , T min , T max ) where T : IComparable < T > =>
122+ value . CompareTo ( min ) is 0 or 1 && value . CompareTo ( max ) is 0 or - 1 ;
123+
124+ /// <summary>
125+ /// Determines whether the current <see cref="IComparable{T}"/> value falls within range, exclusive of the specified minimum and maximum values.
126+ /// </summary>
127+ /// <param name="value">The value to test.</param>
128+ /// <param name="min">The exclusive minimum value.</param>
129+ /// <param name="max">The exclusive maximum value.</param>
130+ /// <typeparam name="T">The underlying <see cref="IComparable{T}"/> type.</typeparam>
131+ /// <returns>
132+ /// Returns <see langword="true"/> if the current <see cref="IComparable{T}"/> value falls within range,
133+ /// exclusive of the specified minimum and maximum values; otherwise, <see langword="false"/>.
134+ /// </returns>
135+ public static bool IsWithinRangeExclusive < T > ( this T value , T min , T max ) where T : IComparable < T > =>
136+ value . CompareTo ( min ) is 1 && value . CompareTo ( max ) is - 1 ;
137+
138+ /// <summary>
139+ /// Calls the specified <see cref="Func{T, TResult}"/> with the current <paramref name="value"/> as its argument and returns the result.
140+ /// </summary>
141+ /// <param name="value">The value to pass to the specified <see cref="Func{T, TResult}"/>.</param>
142+ /// <param name="function">The function into which the current <paramref name="value"/> will be passed.</param>
143+ /// <typeparam name="TSource">The underlying type of the current value.</typeparam>
144+ /// <typeparam name="TResult">The underlying type of the result value.</typeparam>
145+ /// <returns>Returns the result of the specified <see cref="Func{T, TResult}"/>.</returns>
146+ public static TResult Let < TSource , TResult > ( this TSource value , Func < TSource , TResult > function )
147+ {
148+ RequireNotNull ( function , "Function must not be null." , nameof ( function ) ) ;
149+ return function ( value ) ;
150+ }
151+
110152 /// <summary>
111153 /// Gets a record-like <see cref="String"/> representation of the current <see cref="Object"/> instance.
112154 /// <remarks>This method is designed specifically for record-like objects and may produce undesirable results when applied to primitive-like objects.</remarks>
@@ -226,4 +268,23 @@ public static async Task<Optional<T>> ToOptionalAsync<T>(this Task<T?> value, Ca
226268 /// <returns>Returns a <see cref="Success{T}"/> representation of the current <see cref="Object"/>.</returns>
227269 public static async Task < Success < T > > ToSuccessAsync < T > ( this Task < T > value , CancellationToken token = default ) =>
228270 Result < T > . Success ( await value . WaitAsync ( token ) . ConfigureAwait ( false ) ) ;
271+
272+ /// <summary>
273+ /// Attempts to extract a non-null value from the current nullable <see cref="Object"/>.
274+ /// </summary>
275+ /// <param name="value">The current nullable <see cref="Object"/> to test for nullability.</param>
276+ /// <param name="result">The non-null value when this method returns <see langword="true"/>; otherwise, <see langword="null"/>.</param>
277+ /// <typeparam name="T">The underlying type of the value.</typeparam>
278+ /// <returns>Returns <see langword="true"/> if the current nullable <see cref="Object"/> is not null; otherwise, <see langword="false"/>.</returns>
279+ public static bool TryGetNonNull < T > ( this T ? value , [ NotNullWhen ( true ) ] out T result )
280+ {
281+ if ( value is null )
282+ {
283+ result = default ! ;
284+ return false ;
285+ }
286+
287+ result = value ;
288+ return true ;
289+ }
229290}
0 commit comments