C# if-null-then-null expression - c#

Just for curiosity/convenience: C# provides two cool conditional expression features I know of:
string trimmed = (input == null) ? null : input.Trim();
and
string trimmed = (input ?? "").Trim();
I miss another such expression for a situation I face very often:
If the input reference is null, then the output should be null. Otherwise, the output should be the outcome of accessing a method or property of the input object.
I have done exactly that in my first example, but (input == null) ? null : input.Trim() is quite verbose and unreadable.
Is there another conditional expression for this case, or can I use the ?? operator elegantly?

Something like Groovy's null-safe dereferencing operator?
string zipCode = customer?.Address?.ZipCode;
I gather that the C# team has looked at this and found that it's not as simple to design elegantly as one might expect... although I haven't heard about the details of the problems.
I don't believe there's any such thing in the language at the moment, I'm afraid... and I haven't heard of any plans for it, although that's not to say it won't happen at some point.
EDIT: It's now going to be part of C# 6, as the "null-conditional operator".

Currently we can only write an extension method if you don't want to repeat yourself, I'm afraid.
public static string NullableTrim(this string s)
{
return s == null ? null : s.Trim();
}

You can choose between a custom Nullify class or a NullSafe extension method as described here: http://qualityofdata.com/2011/01/27/nullsafe-dereference-operator-in-c/
The usage will be as follows:
//Groovy:
bossName = Employee?.Supervisor?.Manager?.Boss?.Name
//C# Option 1:
bossName = Nullify.Get(Employee, e => e.Supervisor, s => s.Manager,
m => m.Boss, b => b.Name);
//C# Option 2:
bossName = Employee.NullSafe( e => e.Supervisor ).NullSafe( s => s.Boss )
.NullSafe( b => b.Name );

As a workaround you can use this which is based on Maybe monad.
public static Tout IfNotNull<Tin, Tout>(this Tin instance, Func<Tin, Tout> Output)
{
if (instance == null)
return default(Tout);
else
return Output(instance);
}
Use it this way:
int result = objectInstance.IfNotNull(r => 5);
var result = objectInstance.IfNotNull(r => r.DoSomething());

There's nothing built-in, but you could wrap it all up in an extension method if you wanted (although I probably wouldn't bother).
For this specific example:
string trimmed = input.NullSafeTrim();
// ...
public static class StringExtensions
{
public static string NullSafeTrim(this string source)
{
if (source == null)
return source; // or return an empty string if you prefer
return source.Trim();
}
}
Or a more general-purpose version:
string trimmed = input.IfNotNull(s => s.Trim());
// ...
public static class YourExtensions
{
public static TResult IfNotNull<TSource, TResult>(
this TSource source, Func<TSource, TResult> func)
{
if (func == null)
throw new ArgumentNullException("func");
if (source == null)
return source;
return func(source);
}
}

I had the same problem I wrote a few little extension methods:
public static TResult WhenNotNull<T, TResult>(
this T subject,
Func<T, TResult> expression)
where T : class
{
if (subject == null) return default(TResult);
return expression(subject);
}
public static TResult WhenNotNull<T, TResult>(
this T subject, Func<T, TResult> expression,
TResult defaultValue)
where T : class
{
if (subject == null) return defaultValue;
return expression(subject);
}
public static void WhenNotNull<T>(this T subject, Action<T> expression)
where T : class
{
if (subject != null)
{
expression(subject);
}
}
You use it like this;
string str = null;
return str.WhenNotNull(x => x.Length);
or
IEnumerable<object> list;
return list.FirstOrDefault().WhenNotNull(x => x.id, -1);
or
object obj;
IOptionalStuff optional = obj as IOptionalStuff;
optional.WhenNotNull(x => x.Do());
There are also overloads for nullable types.

I know this was already answered by Jon Skeet but this example might be a little more clear example of the Elvis operator ?. (aka the null-conditional member access operator)
string? someValue = (input == null) ? null : input.Trim()
is equivalent to...
string? someValue = input?.Trim();
"Thank You, Thank You Very Much" - Elvis Presley

Related

Testing for 'lazy loaded' null IEnumerable in c#?

I've simplified a piece of a deferred execution code, but how on earth do you check the following is not null/empty without wrapping it in a try/catch?
string[] nullCollection = null;
IEnumerable<string> ienumerable = new[] { nullCollection }.SelectMany(a => a);
bool isnull = ienumerable == null; //returns false
bool isany = ienumerable.Any(); //throws an exception
You just need to make your lambda more resilient to null entries:
IEnumerable<string> ienumerable = new[] { nullCollection }
.SelectMany(a => a ?? Enumerable.Empty<string>());
bool isany = ienumerable.Any(); // Sets isany to 'false'
You cannot do that, because that's the same as asking "how can I tell that method will not throw NullReferenceException without invoking it?". Having no other clues the only way is actually invoke such methods and observe the result. Enumerating IEnumerable is just invoking bunch of MoveNext calls on it's enumerator, and any such call might throw any exceptions.
You can check if the current item from the enumerator is null
string[] nullCollection = null;
IEnumerable<string> ienumerable = new[] { nullCollection }.SelectMany(a => a);
bool isnull = ienumerable.GetEnumerator().Current == null;
if (!isnull)
{
bool isany = ienumerable.Any();
}
Since Linq methods are extension methods on IEnumerable, you could wrap these extensions further: with an extension method, the object receiving the extension can be null.
public static IEnumerable<TResult> SafeSelectMany<T, TCollection, TResult>(
this IEnumerable<T> source,
Func<T, IEnumerable<TCollection>> collectionSelector,
Func<T, TCollection, TResult> resultSelector)
{
if (source == null)
{
return null;
}
IEnumerable<TResult> result = source.SelectMany(collectionSelector, resultSelector);
return result;
}
You could also return an empty List<TResult> instead of null for source==null.

Method chains with nameof operator

If I do nameof(instance.SomeProperty), it evaluates to "SomeProperty".
Is there any way I can get the entire method chain "instance.SomeProperty"?
I know I could do nameof(instance) + "." + nameof(instance.SomeProperty), but is there a better way that's more maintainable?
Is there any way I can get the entire method chain "instance.SomeProperty"?
Nope. You can, however, do something similar to your other solution:
$"{nameof(instance)}.{nameof(instance.SomeProperty)}"
You can try it here.
My 5 cents:
using System;
using System.Linq.Expressions;
public static class Program {
public static void Main() {
Console.WriteLine(Name.Of<A>(x => x.B.Hehe)); // outputs "B.Hehe"
var a = new A();
Console.WriteLine(Name.Of(() => a.B.Hehe)); // outputs "B.Hehe"
}
public class A {
public B B { get; } // property
}
public class B {
public int Hehe; // or field, does not matter
}
}
public static class Name
{
public static string Of(this Expression<Func<object>> expression) => Of(expression.Body);
public static string Of<T>(this Expression<Func<T, object>> expression) => Of(expression.Body);
public static string Of(this Expression expression)
{
switch (expression)
{
case MemberExpression m:
var prefix = Of(m.Expression);
return (prefix == "" ? "" : prefix + ".") + m.Member.Name;
case UnaryExpression u when u.Operand is MemberExpression m:
return Of(m);
default:
return "";
}
}
}
No, there is not. The nameof operator just yields the property (or class, field, etc) at the end of the expression, so nameof(Program.Main) will yield Main, and so does nameof(ConsoleAppliation1.Program.Main).
The nameof operator wasn't meant to do what you ask. It is just prevent passing names around for event handlers, dependency properties, etc. that depend on the sole name of the property / class name. All other fancy stuff you want to do is on your own.
Like M.kazem Akhgary commented, you can do this yourself by constructing the expression yourself:
$"{nameof(instance)}.{nameof(instance.SomeProperty)}"

Expression of type 'MyEnum' cannot be used for parameter of type

I created Enum ToFrendlyString function for my enums, but i cant use in Linq.
public enum MyEnum
{
Queued = 0,
[Description("In progress")]
In_progress = 2,
[Description("No answer")]
No_answer = 6,
}
public static class EnumToFrendlyString
{
public static string ToFrendlyString(this Enum value)
{
return value.GetEnumDescription();
}
public static string GetEnumDescription(this Enum value)
{
FieldInfo fi = value.GetType().GetField(value.ToString());
var attributes =
(DescriptionAttribute[])fi.GetCustomAttributes(
typeof(DescriptionAttribute),
false);
if (attributes.Length > 0)
return attributes[0].Description;
return value.ToString();
}
}
When i try to use this function in Linq, im getting error
var res = collection.AsQueryable().Where(p => p.UserID == UserID).OrderByDescending(p=> p.DateCreated).Select(p => new MyClass
{
Date = p.DateCreated.ToString(),
Status = p.Status.ToFrendlyString(),
}).Take(10).ToList();
If i make another function in same class, like
private string MyStatusToString(MyEnum status)
{
return status.ToFrendlyString();
}
and change my Linq to use this function, then everything works.
Error
Expression of type 'DAL.MyEnum' cannot be used for parameter of type 'System.Enum' of method 'System.String ToFrendlyString(System.Enum)'
I'm not sure you can use Enum as the Type for an extension method like that - try this instead. I've taken the liberty of tidying the code up a bit, feel free to ignore those changes :)
public static class EnumToFrendlyString
{
public static string ToFrendlyString<T>(this T value)
where T : struct
{
return value.GetEnumDescription();
}
public static string GetEnumDescription<T>(this T value)
where T : struct
{
return EnumDescriptionCache<T>.Descriptions[value];
}
private static class EnumDescriptionCache<T>
where T : struct
{
public static Dictionary<T, string> Descriptions =
Enum.GetValues(typeof(T))
.Cast<T>()
.ToDictionary(
value => value,
value => value.GetEnumDescriptionForCache());
}
private static string GetEnumDescriptionForCache<T>(this T value)
where T : struct
{
if (!typeof(T).IsEnum)
{
throw new ArgumentException("Only use with enums", "value");
}
var descriptionAttribute = typeof(T)
.GetField(value.ToString())
.GetCustomAttributes(typeof(DescriptionAttribute), false)
.Cast<DescriptionAttribute>()
.FirstOrDefault();
return (descriptionAttribute != null)
? descriptionAttribute.Description
: value.ToString();
}
}
I've added a private, generic class to cache the descriptions for your enum members to avoid lots of runtime use of reflection. It looks a bit odd popping in and out of the class to first cache then retrieve the values, but it should work fine :)
The warning I gave in this answer still applies - the enum value passed to the dictionary isn't validated, so you could crash it by calling ((MyEnum)5367372).ToFrendlyString().
I am not sure but it can be that you didn t add the DAL project yet to your current project(Add reference -> projects in solutins -> Dal). Then it might work. (I had a similar issue once and this was my solution)
It seems the problem is that your collection is IQueryable<T> and the query provider is trying to translate your Select() into a query string.
One way to avoid that is to perform Select() in memory using IEnumerable<T>:
var res = collection.AsQueryable()
.Where(p => p.UserID == UserID)
.OrderByDescending(p=> p.DateCreated)
.Take(10)
.AsEnumerable()
.Select(p => new MyClass
{
Date = p.DateCreated.ToString(),
Status = p.Status.ToFrendlyString(),
})
.ToList();

In LINQ, select all values of property X where X != null

Is there a shorter way to write the following? (Something that would check for null without explicitly writing != null)
from item in list
where item.MyProperty != null
select item.MyProperty
You can use the OfType operator. It ignores null values in the source sequence. Just use the same type as MyProperty and it won't filter out anything else.
// given:
// public T MyProperty { get; }
var nonNullItems = list.Select(x => x.MyProperty).OfType<T>();
I would advise against this though. If you want to pick non-null values, what can be more explicit than saying you want "the MyProperties from the list that are not null"?
You could define your own extension method, but I wouldn't recommend that.
public static IEnumerable<TResult> SelectNonNull<T, TResult>(this IEnumerable<T> sequence,Func<T, TResult> projection)
{
return sequence.Select(projection).Where(e => e != null);
}
I don't like this one because it mixes two concerns. Projecting with Select and filtering your null values are separate operations and should not be combined into one method.
I'd rather define an extension method that only checks if the item isn't null:
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T> sequence)
{
return sequence.Where(e => e != null);
}
public static IEnumerable<T> WhereNotNull<T>(this IEnumerable<T?> sequence)
where T : struct
{
return sequence.Where(e => e != null).Select(e => e.Value);
}
This has only a single purpose, checking for null. For nullable value types it converts to the non nullable equivalent, since it's useless to preserve the nullable wrapper for values which cannot be null.
With this method, your code becomes:
list.Select(item => item.MyProperty).WhereNotNull()
I tend to create a static class containing basic functions for cases like these. They allow me write expressions like
var myValues myItems.Select(x => x.Value).Where(Predicates.IsNotNull);
And the collection of predicate functions:
public static class Predicates
{
public static bool IsNull<T>(T value) where T : class
{
return value == null;
}
public static bool IsNotNull<T>(T value) where T : class
{
return value != null;
}
public static bool IsNull<T>(T? nullableValue) where T : struct
{
return !nullableValue.HasValue;
}
public static bool IsNotNull<T>(T? nullableValue) where T : struct
{
return nullableValue.HasValue;
}
public static bool HasValue<T>(T? nullableValue) where T : struct
{
return nullableValue.HasValue;
}
public static bool HasNoValue<T>(T? nullableValue) where T : struct
{
return !nullableValue.HasValue;
}
}
There is no way to skip a check if it exists.
// if you need to check if all items' MyProperty doesn't have null
if (list.All(x => x.MyProperty != null))
// do something
// or if you need to check if at least one items' property has doesn't have null
if (list.Any(x => x.MyProperty != null))
// do something
But you always have to check for null
get one column in the distinct select and ignore null values:
var items = db.table.Where(p => p.id!=null).GroupBy(p => p.id)
.Select(grp => grp.First().id)
.ToList();
This is adapted from CodesInChaos's extension method. The name is shorter (NotNull) and more importantly, restricts the type (T) to reference types with where T : class.
public static IEnumerable<T> NotNull<T>(this IEnumerable<T> source) where T : class
{
return source.Where(item => item != null);
}
I know i am a bit late to the party but I found a IMO very elegant sollution to this problem. I wrote an extension method to chain onto my LINQ queries:
public static IEnumerable<T> DiscardNullValues<T>(this IEnumerable<T?> nullable)
{
foreach (var item in nullable)
{
if (item is not null) yield return item;
}
}
Works like a charm.
This is a feature that have been proposed to the dotnet/runtime issue tracker.
See this comment that proposes a SelectNotNull function :
https://github.com/dotnet/runtime/issues/30381#issuecomment-806396119

Generically checking for null that won't box nullables on a non-constrained type.

Let's say I have the following method:
public static int CountNonNullMembers<T>(this IEnumerable<T> enumerable)
{
if (enumerable == null) throw new ArgumentNullException("enumerable");
int count = 0;
foreach (var x in enumerable)
{
if (x != null) count++;
}
return count;
}
And I have these 3 arrays::
var ints = Enumerable.Range(0,10).ToArray();
var nullableInts = Array.ConvertAll(ints,x=>x as int?);
var strings = Array.ConvertAll(ints,x => x.ToString());
I wrote a little function to do a loop and time it for a million iterations. Applying it to ints and strings, it finishes in about 100 ms on my machine. For nullableInts, it takes 2.5 seconds.
As I understand the check for null on int doesn't make sense, so the compiler has a different template for non-nullable struct types, that removes null checks. But Nullable<T> does not have a template that converts the null check to x.HasValue. If I have an unconstrained function, how can I do a null check that will perform well? I can't use EqualityComparer<T>, as null might not be a member of T as there is no constraint.
Also it's impossible to have overloads that differ by constraint, so I can't, say, have one for structs, one for Nullable<T>, and one for classes.
The caller of the method is non-constrained. This is just an example (not the actual method); the method calling is non-constrained. I need to do some work against non-null members, and it's a generic method. I suppose I could write a version that doesn't do the check vs one that does (and consequently has a different signature), but it's seems very ugly and unneeded.
Also, the extension method .Count inexplicably performs horribly for NullableInts and strings, (equally bad), so it really isn't the right approach. This might be the delegate invocation, but I doubt it. Using the UnboxT style method of Check<T>.IfNull performs a lot better.
Okay, really weird switching the body of the count to this performs great:
public static int CountNonNullMembers<T>(this IEnumerable<T> enumerable)
{
return enumerable.Count(Check<T>.IfNull.Invoke);
}
Why?
You can constrain generic type parameters to reference types or values types:
public static int CountNonNull<T>(this IEnumerable<T> source)
where T : class
{
return source.Count(x => x != null);
}
public static int CountNonNull<T>(this IEnumerable<Nullable<T>> source)
where T : struct
{
return source.Count(x => x.HasValue);
}
You don't need an overload for non-nullable structs, because they can't be null anyway.
Using the UnboxT approach works. But I'd also like something that doesn't require creating a static type::
public static class Check<T>
{
public static readonly Predicate<T> IfNull = CreateIfNullDelegate();
private static bool AlwaysFalse(T obj)
{
return false;
}
private static bool ForRefType(T obj)
{
return object.ReferenceEquals(obj, null);
}
private static bool ForNullable<Tu>(Tu? obj) where Tu:struct
{
return !obj.HasValue;
}
private static Predicate<T> CreateIfNullDelegate()
{
if (!typeof(T).IsValueType)
return ForRefType;
else
{
Type underlying;
if ((underlying = Nullable.GetUnderlyingType(typeof(T))) != null)
{
return Delegate.CreateDelegate(
typeof(Predicate<T>),
typeof(Check<T>)
.GetMethod("ForNullable",BindingFlags.NonPublic | BindingFlags.Static)
.MakeGenericMethod(underlying)
) as Predicate<T>;
}
else
{
return AlwaysFalse;
}
}
}
}
Using this approach everything performs about the same. Strings performs worse, but not so much worse than everything else.
While not necessarily better than your method, it doesn't require a whole class:
static Dictionary<Type, object> NullChecks = new Dictionary<Type, object>();
public static Func<T, bool> MakeNullCheck<T>()
{
object obj;
Func<T, bool> func;
if (NullChecks.TryGetValue(typeof(T), out obj))
return (Func<T, bool>)obj;
if (typeof(T).IsClass)
func = x => x != null;
else if (Nullable.GetUnderlyingType(typeof(T)) != null)
{
var param = Expression.Parameter(typeof(T));
func = Expression.Lambda<Func<T, bool>>(
Expression.Property(param, typeof(T).GetProperty("HasValue")), param).Compile();
}
else
func = x => false;
NullChecks[typeof(T)] = func;
return func;
}

Categories

Resources