C# elegant way to check if a property's property is null
In C# 6 you can use the Null Conditional Operator. So the original test will be:
int? value = objectA?.PropertyA?.PropertyB?.PropertyC;
VB equiv - Elegant way to check if a property's property is null
Yes. The null-conditional operator (MSDN) also exists in VB.NET (VB 14 and above, i.e., Visual Studio 2015 and above) and has the same syntax:
Dim value As Int32? = objectA?.PropertyA?.PropertyB?.PropertyC
Often, this is combined with the null-coalescing operator, which is a ?? b
in C# and If(a, b)
in VB.NET:
Dim value As Int32 = If(objectA?.PropertyA?.PropertyB?.PropertyC, 0) ' Default value if null
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();
}
}
}
}
How to check with C#, in more elegant way, if only some of the object properties are null?
There's many ways of doing this, perhaps one of the more easily readable is:
var o = new SomeObjectType // object is a keyword
{
Prop1 = null,
Prop2 = null,
Prop3 = 665
};
if(o is SomeObjectType { Prop1: null, Prop2: null } )
; // do stuff
Cleaner way to do a null check in C#?
In a generic way, you may use an expression tree and check with an extension method:
if (!person.IsNull(p => p.contact.address.city))
{
//Nothing is null
}
Full code:
public class IsNullVisitor : ExpressionVisitor
{
public bool IsNull { get; private set; }
public object CurrentObject { get; set; }
protected override Expression VisitMember(MemberExpression node)
{
base.VisitMember(node);
if (CheckNull())
{
return node;
}
var member = (PropertyInfo)node.Member;
CurrentObject = member.GetValue(CurrentObject,null);
CheckNull();
return node;
}
private bool CheckNull()
{
if (CurrentObject == null)
{
IsNull = true;
}
return IsNull;
}
}
public static class Helper
{
public static bool IsNull<T>(this T root,Expression<Func<T, object>> getter)
{
var visitor = new IsNullVisitor();
visitor.CurrentObject = root;
visitor.Visit(getter);
return visitor.IsNull;
}
}
class Program
{
static void Main(string[] args)
{
Person nullPerson = null;
var isNull_0 = nullPerson.IsNull(p => p.contact.address.city);
var isNull_1 = new Person().IsNull(p => p.contact.address.city);
var isNull_2 = new Person { contact = new Contact() }.IsNull(p => p.contact.address.city);
var isNull_3 = new Person { contact = new Contact { address = new Address() } }.IsNull(p => p.contact.address.city);
var notnull = new Person { contact = new Contact { address = new Address { city = "LONDON" } } }.IsNull(p => p.contact.address.city);
}
}
Null check on a property error
_someObj?.IsActive
is a nullable condition, so assuming IsActive
is of type bool
, using ?.
will turn the result to a nullable bool bool?/Nullable<bool>
which will conflict with the expected bool
result of the property.
If _someObj
is null then the result will also be null, so you will need to add a null-coalescing operator for that possibility
public bool IsActive {
get { return _someObj?.IsActive ?? false; }
}
Check All Child Properties For Null in C#
Currently in C#, you can't, you have to individually check each property for null.
May be you are looking for ".?" operator, but its not there in C# 4.0, Check out this post and the response from Eric Lippert: Deep null checking, is there a better way?
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 ?[]
.
Related Topics
How to Compare Two Rich Text Box Contents and Highlight the Characters That Are Changed
How to Make Multi-Language App in Winforms
Using the Iterator Variable of Foreach Loop in a Lambda Expression - Why Fails
Avoiding First Chance Exception Messages When the Exception Is Safely Handled
MVC Razor View Nested Foreach's Model
How to Fix the Microsoft Visual Studio Error: "Package Did Not Load Correctly"
Memory Allocation: Stack VS Heap
C# Image Resizing to Different Size While Preserving Aspect Ratio
Find a Control in Windows Forms by Name
Properly Draw Text Using Graphicspath
Escape Special Character in Regex
Export to Excel from a List with Epplus
How to Update Textbox in Form1 from Form2