patterncsharpMinor
Calling a function on an object if not null
Viewed 0 times
nullfunctionobjectcallingnot
Problem
Here is code for check
The above code is best pratice of check nullability in object. I'm working on c# V4.0.
Example usage :
null in object:public static TResult IfNotNull(this TInput obj, Func expression)
{
if (obj == null || expression == null) return default(TResult);
var value = expression(obj);
return value;
}The above code is best pratice of check nullability in object. I'm working on c# V4.0.
Example usage :
Person.IfNotNull(x => x.User).IfNotNull(x => x.Name) ?? "";Solution
To be sure it always works you should add a constraint to the method:
This will ensure that
It makes no sense to call it on structs. For them, you need another overload with a different constraint and some
Someone may ask at this point: but why do we need two extensions if theoretically a single one does the job too?
Consider this:
With a single extension you need to use the
But isn't this just a convenience? Of course it is. Don't we write extensions exactly for that reason?
As a matter of fact I use a similar code myself:
but you can create a simplified version of your method and combine it with the
to do this
where TInput : classThis will ensure that
TInput is a reference type.It makes no sense to call it on structs. For them, you need another overload with a different constraint and some
? question marks:public static TResult IfNotNull(
this TInput? obj,
Func expression
) where TInput : struct
{
if (!obj.HasValue) return default(TResult);
var value = expression(obj.Value);
return value;
}Someone may ask at this point: but why do we need two extensions if theoretically a single one does the job too?
Consider this:
((decimal?)2).IsNotNull(x => x.Value * 2)With a single extension you need to use the
.Value property for nullable types. With two extensions you get a clean value so you just do ((decimal?)2).IsNotNull(x => x * 2)But isn't this just a convenience? Of course it is. Don't we write extensions exactly for that reason?
As a matter of fact I use a similar code myself:
public static TResult IIf
(
this TArg arg,
Func predicate,
Func ifTrue,
Func ifFalse = null
)
{
if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); }
if (ifTrue == null) { throw new ArgumentNullException(nameof(ifTrue)); }
return predicate(arg) ? ifTrue(arg) : (ifFalse == null ? default(TResult) : ifFalse(arg));
}but you can create a simplified version of your method and combine it with the
IIfpublic static bool IsNotNull(this TInput obj) where TInput : class
{
return obj != null;
}to do this
Person
.IIf(p => p.IsNotNull(), p => p.User)
.IIf(u => u.IsNotNull(), u => u.Name, u string.Empty);Code Snippets
where TInput : classpublic static TResult IfNotNull<TInput, TResult>(
this TInput? obj,
Func<TInput, TResult> expression
) where TInput : struct
{
if (!obj.HasValue) return default(TResult);
var value = expression(obj.Value);
return value;
}((decimal?)2).IsNotNull(x => x.Value * 2)((decimal?)2).IsNotNull(x => x * 2)public static TResult IIf<TArg, TResult>
(
this TArg arg,
Func<TArg, bool> predicate,
Func<TArg, TResult> ifTrue,
Func<TArg, TResult> ifFalse = null
)
{
if (predicate == null) { throw new ArgumentNullException(nameof(predicate)); }
if (ifTrue == null) { throw new ArgumentNullException(nameof(ifTrue)); }
return predicate(arg) ? ifTrue(arg) : (ifFalse == null ? default(TResult) : ifFalse(arg));
}Context
StackExchange Code Review Q#146483, answer score: 6
Revisions (0)
No revisions yet.