How do I determine if an object reference is null in C# w/o throwing an exception if it is null?
i.e. If I have a class reference being passed in and I don't know if it is null or not.
testing against null will never* throw an exception
void DoSomething( MyClass value )
{
if( value != null )
{
value.Method();
}
}
* never as in should never. As #Ilya Ryzhenkov points out, an incorrect implementation of the != operator for MyClass could throw an exception. Fortunately Greg Beech has a good blog post on implementing object equality in .NET.
What Robert said, but for that particular case I like to express it with a guard clause like this, rather than nest the whole method body in an if block:
void DoSomething( MyClass value )
{
if ( value == null ) return;
// I might throw an ArgumentNullException here, instead
value.Method();
}
Note, that having operator != defined on MyClass would probably lead do different result of a check and NullReferenceException later on. To be absolutely sure, use object.ReferenceEquals(value, null)
if(p != null)
{
DoWork(p);
}
Also, the 'as' keyword is helpful if you want to detect if a class is of the right type and use it all at once.
IExample e = p as IExample;
if(e != null)
DoWork(e);
In the above example if you were to cast e like (IExample)e it will throw an exception if e does not implement IExapmle. If you use 'as' and e doesn't implement IExample e will simply be null.
If you look in the majority of the .NET framework source code you will see they put checks like this at the top of their functions.
public void DoSomething(Object myParam)
{
if (myParam == null) throw new ArgumentNullException("myParam");
// Carry on
}
With C# 6.0 this is much more elegant; you can do it in one line :-)
value?.Method();
If "value" is null, nothing will happen - and no exception.
It's nit picky, but I always code these like ...
if (null == obj) {
obj = new Obj();
}
instead of
if (obj == null) {
obj = new Obj();
}
to avoid accidently writing
if (obj = null) {
obj = new Obj();
}
because
if (null = obj) {
obj = new Obj();
}
will give you a compiler error
Or if you are using value types you can read about nullable types: http://www.c-sharpcorner.com/UploadFile/mosessaur/nullabletypes08222006164135PM/nullabletypes.aspx
(YourObject != Null)
you can compare to null?
If it's null instead of throwing an exception you can initialize your object. You can use the Null Pattern.
I have in the application's xaml.cs application derivative definition:
private SortedList myList;
And I want to be able to re-use my constructors. So I needed:
if ( myList == null)
myList = new SortedList();
Thanks Robert!
Related
So I know why I have a null reference exception in this case. My question is how I avoid it given this specific use.
I have a function interpreting JSON data like so:
public IActionResult SendLine([FromBody] User data) {
if (_assets.GetPropertyByName(data.Properties.PropertyName) == null) {
_assets.AddProperty(new Property {
IsToggle = data.Properties.IsToggle,
Order = data.Propertis.Order,
Type = data.Properties.Type,
PropertyName = data.Properties.PropertyName
});
}
_assets.AddRow(data);
return Json(data);
}
The problem is that the Property class can have null values like so:
{
properties: {
isToggle: false,
order: 0,
type: null,
propertyName: "Test"
},
....
}
So I get why it throws the exception that "properties" is null since it has a null value. However this is as intended. How do I check to see if the propertyName is null without it throwing that error?
EDIT:
I'm not sure how null conditionals would help this case. If I put it here
if (_assets.GetPropertyByName(data.Properties?.PropertyName) == null)
it will evaluate to null improperly.
Edit: Updated my answer after realizing this is probably closer to what you need (?):
If the if-clause is where your exception is thrown, just split it up a little more:
var propName = data?.Properties?.PropertyName;
var isPropNameFound = !string.IsNullOrEmpty(propName);
var prop = isPropNameFound ? _assets.GetPropertyByName(propName) : null;
if (isPropNameFound && (prop == null))
{
// Add new property if name was given, and it
// was not found to already have been added?
}
That should ensure propName is null if either data.Properties or data.Properties.PropertyName is null, and do so without throwing a NullReferenceException.
After that, it will run the logic in the if block only if propName had a value, and if _assets.GetPropertyByName(propName) did not return anything.
In this event handler:
public static void geolocator_PositionChanged(Geolocator sender, PositionChangedEventArgs args)
{
DateTimeOffset timeStampUTC = args.Position.Coordinate.Timestamp.ToUniversalTime();
DateTimeOffset timeStampLocal = timeStampUTC.LocalDateTime;
DateTimeOffset dateTimeStampUTC = timeStampUTC.DateTime;
RecordLocation(args.Position.Coordinate.Latitude, args.Position.Coordinate.Longitude,
args.Position.CivicAddress.City, args.Position.CivicAddress.State, dateTimeStampUTC, timeStampLocal);
}
...I'm getting a Null Reference Exception because args.Position.CivicAddress is null (the rest of the args passed to RecordLocation() are valid). I reckon sometimes Position will be null, and sometimes it won't. What can I do to let the times when no City or State is found pass through unabated? I tried to make those strings in RecordLocation()'s definition nullable, but that won't compile.
Do I need to check CivicAddress for null and create an overloaded version of my RecordLocation() method, or is there another way to handle this?
What can I do to let the times when no City or State is found pass through unabated?
You just need to check it. For example:
if (args.Position != null && args.Position.CivicAddress != null)
{
// Now you can use args.Position.CivicAddress.State safely
}
If you want to do lots of things with args.Position, you quite possibly want one "outer" if statement - quite possibly with a local variable to simplify things:
var position = args.Position;
if (position != null)
{
if (position.CivicAddress != null)
{
// Use properties of position.CivicAddress
}
// Assuming Coordinate is nullable to start with, of course...
if (position.Coordinate != null)
{
// ...
}
}
So I have a Retrieve() function, which either gets me an object or a null (if that object is not found). I'm using an if statement with a boolean attribute of that object. It's set up like this.
if(Retrieve(index).IsForm == true) {}
The issue with this is that if it doesn't find an object, it'll throw a null reference exception. There are some ways around this, of course, but none that I find concise. There's a try...catch, but that seems pointless when I expect the error. I can check if the object is null first, if(Retrieve(index) != null), but that seems like adding needless nesting. Is there a clever way to handle this? I thought of using the null coalescing operator but it doesn't work in this situation.
You can either call the method twice:
if(Retrieve(index) != null && Retrieve(index).IsForm == true) { }
Or you can break the lines apart and store the result before the if:
var result = Retrieve(index);
if(result != null && result.IsForm == true) { }
You could write an IsForm function to do both operations for you:
bool IsForm(int index)
{
var result = Retrieve(index);
return result != null && result.IsForm;
}
if (IsForm(index))
...
The Null Object pattern would be helpful here. It keeps your calling code clean but does add an additional class.
class NullWhatever : Whatever
{
public NullWhatever() { IsForm = false; }
}
Whatever Retrieve(...)
{
...
return new NullWhatever(); // instead of null
}
You could make a Nullable_IsForm extension method. Then you could check for the null condition.
public static class RetrieveExtension
{
public static bool? Nullable_IsForm(this Retrieve retrieved)
{
if(retrieved == null)
{
return null;
}
else
{
return retrieved.IsForm;
}
}
}
Then in your code you'd check it against bool values
if(Retrieve(index).Nullable_IsForm == true)
{}
else if (Retrieve(index).Nullable_IsForm == false)
{}
else if (Retrieve(index).Nullable_IsForm == null )
{}
I don't think there is any more concise way to do it, no.
Shortest I can think of is:
if(Retrieve(index)!=null && Retrieve(index).IsForm == true) {}
but I don't like this because it calls Retrieve(index) multiple times. I'd go for
var foo = Retrieve(index);
if(foo!=null && foo.IsForm == true) {}
but that is obviously not doing anything clever or more concise. It is probably more efficeint than some of the alternatives.
You could put both conditions in the same if:
if(Retrieve(index)!= null && Retrieve(index).IsForm == true) {}
Thanks to short-circuit, if the null-check fails, rest of the expression is not evaluated.
I have a class property that is a list of strings, List.
Sometimes this property is null or if it has been set but the list is empty then count is 0.
However elsewhere in my code I need to check whether this property is set, so currently my code check whether it's null and count is 0 which seems messy.
if(objectA.folders is null)
{
if(objectA.folders.count == 0)
{
// do something
}
}
Any recommendation on how this should be handled?
Maybe I should always initialise the property so that it's never null?
When I have List as a property, I usually have something that looks like the following (this is not a thread safe piece of code):
public class SomeObject
{
private List<string> _myList = null;
public List<string> MyList
{
get
{
if(_myList == null)
_myList = new List<string>();
return _myList;
}
}
}
Your code would then never have to check for null because the Property would be initialized if used. You would then only have to check for the Count.
Right now your code will Always throw a Null Pointer exception, you are checking for Null and if it IS null - you're trying to access an object which does not exist.
If for your application the collection being a null reference never has a different meaning than the collection being empty, then yes, I would say you should always initialize it and this way remove the null checks from the remaining code.
This approach only makes sense if the property setter does not allow to change it to a null reference after initialization.
You have three options (and you need to decide based on your project):
Create a method to check for NullOrNoElements. Pro: Allows both null and no entries. Con: You have to call it everywhere you want to use the property.
Preinitialize with a list. Pro: Thread-save and very easy. Con: will use memory even when not used (depending on how many instances you have this may be a problem)
Lazy initialize Pro: Does only use memory when really used. Con: NOT thread save.
private List<string> lp = null;
public List<string> ListProp
{
get
{
if(lp == null)
lp = new List<string>();
return lp;
}
}
You could always initialize the property so it's an empty List. Then you can just check the count property.
List<String> Folder = Enumerable.Empty<String>();
I once wrote an extension method for ICollection objects that checked if they were null or empty
public static Boolean IsNullOrEmpty<T>(this ICollection<T> collection)
{
return collection == null ? true : collection.Count() == 0;
}
public static Boolean IsPopulated<T>(this ICollection<T> collection)
{
return collection != null ? collection.Count() > 0 : false;
}
You could do this in a single IF
if(objectA.folders is null || objectA.folders.count == 0)
Or you could create a boolean property in the class which checks this status for you and returns a result
public bool objectA.FolderIsNullOrEmpty
{
get { return objectA.folders is null || objectA.folders.count == 0;}
}
If it does not make a difference to your application, I would rather recomend initializing the List to start with.
You could handle this by initializing the object in the constructor. This is usually where this type of thing is done. Although I see nothing wrong with your current code. No point in initializing stuff that doesn't exist yet, it just wastes memory.
Its a good question. I would add a method to objectA FoldersNullOrEmpty() that you can use eg
public virtual FoldersNullOrEmpty()
{
return (folders == null || folders.count == 0)
}
I almost always initialize lists and even make sure they can't be set to null if exposed by any setters. This makes using them much easier.
if (alMethSign[z].ToString().Contains(aClass.Namespace))
Here, I load an exe or dll and check its namespace. In some dlls, there is no namespace, so aclass.namespace is not present and it's throwing a NullReferenceException.
I have to just avoid it and it should continue with rest of the code. If I use try-catch, it executes the catch part; I want it to continue with the rest of the code.
Don't catch the exception. Instead, defend against it:
string nmspace = aClass.Namespace;
if (nmspace != null && alMethSign[z].ToString().Contains(nmspace))
{
...
}
Is aClass a Type instance? If so - just check it for null:
if (aClass != null && alMethSign[z].ToString().Contains(aClass.Namespace))
Add the test for null in the if statement.
if(aClass.NameSpace != null && alMethSign[z].ToString().Contains(aClass.Namespace))
Or use an extension method to that checks for any nulls and either returns an empty string or the string value of the object:
public static string ToSafeString(this object o)
{
return o == null ? string.Empty : o.ToString();
}