Deep null checking, is there a better way?
We have considered adding a new operation "?." to the language that has the semantics you want. (And it has been added now; see below.) That is, you'd say
cake?.frosting?.berries?.loader
and the compiler would generate all the short-circuiting checks for you.
It didn't make the bar for C# 4. Perhaps for a hypothetical future version of the language.
Update (2014):
The ?.
operator is now planned for the next Roslyn compiler release. Note that there is still some debate over the exact syntactic and semantic analysis of the operator.
Update (July 2015): Visual Studio 2015 has been released and ships with a C# compiler that supports the null-conditional operators ?.
and ?[]
.
Deep null check inside linq expression, is there a better way?
Try to do not do any null checks in LINQ to Entities query. EF should handle nulls automatically:
_collection.Select(x=> new CollectionModel
{
Title = x.CollectionValues!.FirstOrDefault(x => x.Amount == amount)!
.TranslationTitle.TranslationValues!
.FirstOrDefault(x => x.LanguageId == languageId)!
.Value ?? ""
}
);
Eliminate IF checks in LINQ deep structure
You can create a simple extension method capable of applying a projection to a possibly null value that propagates null values instead of throwing an exception: (Note that different people like using different names for this operation; feel free to call the method whatever makes the most sense to you.)
public static TResult Use<TSource, TResult>(
this TSource obj, Func<TSource, TResult> selector)
where TSource : class
where TResult : class
{
return obj == null ? null : selector(obj);
}
With this your code can be condensed into the following:
var name = doc.Root.Element("E1")
.Use(element => element.Elements("E2"))
.Use(elements => elements.SingleOrDefault(
element => element.Attribute("id")
.Use(att => att.Value) == "ABC"))
.Use(element => element.Attribute("name").Value);
C# elegant way to check if all shallow properties are null (or any property is not null)
Frankly, I'd stick with the simple version involving ||
or &&
, == null
or != null
. It it direct and efficient, and allows immediate short-circuiting. If you are going to be doing this lots, you could perhaps write a utility class that uses meta-programming (Expression
or ILGenerator
maybe) to create an optimized method once per-type that checks all the properties, then:
if(MyHelper.AllNull(obj)) ... // note this is probably actually generic
Full example:
using System;
using System.Linq.Expressions;
using System.Reflection;
static class Program
{
static void Main()
{
bool x = MyHelper.AnyNull(new Foo { }); // true
bool y = MyHelper.AnyNull(new Foo { X = "" }); // false
}
}
class Foo
{
public string X { get; set; }
public int Y { get; set; }
}
static class MyHelper
{
public static bool AnyNull<T>(T obj)
{
return Cache<T>.AnyNull(obj);
}
static class Cache<T>
{
public static readonly Func<T, bool> AnyNull;
static Cache()
{
var props = typeof(T).GetProperties(
BindingFlags.Instance | BindingFlags.Public);
var param = Expression.Parameter(typeof(T), "obj");
Expression body = null;
foreach(var prop in props)
{
if (!prop.CanRead) continue;
if(prop.PropertyType.IsValueType)
{
Type underlyingType = Nullable.GetUnderlyingType(
prop.PropertyType);
if (underlyingType == null) continue; // cannot be null
// TODO: handle Nullable<T>
}
else
{
Expression check = Expression.Equal(
Expression.Property(param, prop),
Expression.Constant(null, prop.PropertyType));
body = body == null ? check : Expression.OrElse(body, check);
}
}
if (body == null) AnyNull = x => false; // or true?
else
{
AnyNull = Expression.Lambda<Func<T, bool>>(body, param).Compile();
}
}
}
}
Is there a more innovative way to handle null exceptions in the following cases?
If you want to just provide new Veet Object if puppy.getVet()
is null by using orElseGet
Vet vet = Optional.ofNullable(puppy.getVet()).orElseGet(Vet::new);
If you want to provide default Veet Object if puppy.getVet()
is null
Vet vet = Optional.ofNullable(puppy.getVet()).orElseGet(PuppyResponse::getDefaultVet);
This way you don't need to check ifPresent and create responses accordingly
return new PuppyResponse(
puppy.getPuppyId(),
puppy.getName(),
puppy.getAge(),
puppy.getBreed(),
vet.getVetId(),
vet.getName()
);
To provide default Vet Object
private static Vet getDefaultVet(){
Vet v = new Vet();
v.setVetId(0);
v.setName("Default Name");
return v;
}
Related Topics
How to Read a File Even When Getting an "In Use by Another Process" Exception
How Using Try Catch for Exception Handling Is Best Practice
Fixed Size Queue Which Automatically Dequeues Old Values Upon New Enques
Using Linq to Group a List of Objects into a New Grouped List of List of Objects
Cannot Delete Directory with Directory.Delete(Path, True)
Get Connection String from App.Config
How to Know If a Process Is Running
Inner Join of Datatables in C#
C# - Multiple Generic Types in One List
Making a Simple Ajax Call to Controller in ASP.NET MVC
C# Switch Statement Limitations - Why
How to Merge Multiple Assemblies into One
How to Apply Orderby on an Iqueryable Using a String Column Name Within a Generic Extension Method
Xml Serialization - Hide Null Values
Callback When Dependency Property Recieves Xaml Change