Is there a clever way to handle this null object reference? - c#

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.

Related

question mark operator not working with count

Following is my null operator check
if (vessels?.Vessels?.Count == 0)
{ }
and object is below
private static readonly DataQueueItem _emptyVessel = new DataQueueItem()
{
VesselId = 1,
Vessels = null
};
It is going in else part but it should be in if block.
I am confused why it is happening.
Any help
Please change your code into =>
if ((vessels?.Vessels?.Count ?? 0) == 0)
{
// do something.
}
Explanation: As vessels can be null or vessels.Vessels can be null so, vessels?.Vessels?.Count will return (int?) type. At the same time, in the if condition if (vessels?.Vessels?.Count == 0) in the question, we are trying check a (int?)==(int). Which might not worked as you expected. We can not check null to a value. That's why I have added (vessels?.Vessels?.Count ?? 0). That part will return 0 if vessels?.Vessels?.Count is null. So, value will be checked with a value.
Do this instead:
if (vessels.Vessels == null)
{
// Code
}
The null keyword is a literal that represents a null reference, one that does not refer to any object. null is not the same as 0.

Way to check for null value in if condition

I have the following line of code, which is giving me trouble of NPE
ServeUrl = ((NameValueCollection)ConfigurationManager.GetSection("Servers")).Get(ment);
When I write this in the following way, I no longer get the NPE
if (ConfigurationManager.GetSection("Servers") != null && ((NameValueCollection)ConfigurationManager.GetSection("Servers")).Get(ment) != null)
{
ServeUrl = ((NameValueCollection)ConfigurationManager.GetSection("Servers")).Get(ment);
}
Somwhow, the above thing does not look good to my eyes. How can I write this in a better way?
I'd extract a temporary variable:
var section = (NameValueCollection)ConfigurationManager.GetSection("Servers");
if (section != null && section.Get(ment) != null)
{
...
}
Or even:
var section = (NameValueCollection)ConfigurationManager.GetSection("Servers");
if (section != null)
{
var url = section.Get(ment);
if (url != null)
{
ServeUrl = url;
}
}
What would you want to do if GetSection returned null though? Can you actually keep going?
!= means not equal to and == means equal to
If you can't use NULL you can use ""
Apply the condition with logic and then even after it is not getting what you want then:
condition will be false and you also used AND logical operator
I would have used this(FYI,i haven't tried this in compiler):
if (ConfigurationManager.GetSection("Servers")?.Get(ment) is NameValueCollection nvc)
{
ServeUrl = nvc;
}

Double If Else Problem in C#

I constantly find myself writing similar code like the example below:
if (object["Object Name"] != null) {
if (object["Object Name"] == "Some Value") {
// Do Statement A
} else {
// Do Statement B
}
} else {
// Do Statement B
}
The problem here is that I much check if an object is null or not and then I can check it for it's actual contents.
"Statement B" is always the same and in my case is usually a SQL statement.
There must be a better way around this?
Thanks
Stephen
There is short circuiting in C# so you can do:
if(null != object && object.name == foo)
do A
else
do B
C# always evaluates the first expression in the conditional statement first and if that fails, it doesn't try anything else in that part of the statement.
To further this point, if you are going to have an expensive operation in the conditional statement along with one or more inexpensive operations, it's good to put it at the end if possible, so it will only check the expensive operation when it really needs to. So something like
if(trivial comparison && trivial comparison && REALLY EXPENSIVE OPERATION)
It will now only execute the expensive operation as a last resort.
Since C# does short circuiting, yes. Try this:
if (object["Object Name"] != null && object["Object Name"] == "Some Value")
{
// Do Statement A
}
else
{
// Do Statement B
}
I think rewriting the if-then-else to this will make it look nicer because of the single B-statement.
if ((object["Object Name"] != null) && (object["Object Name"] == "Some Value"))
{
// Do Statement A
}
else
{
// Do Statement B
}
Why the double check? Surely this would be sufficient:
if(object["Object Name"] == "Some Value") {
// Do statement A
} else {
// Do statement B
}
I sort of see what you're getting at with null checking, but the particular example you give doesn't require it.
EDIT: Now if you had written this instead:
if (object != null) {
if (object["Object Name"] == "Some Value") {
// Do Statement A
} else {
// Do Statement B
}
} else {
// Do Statement B
}
then the solution would be:
if(object != null && object["Object Name"] == "Some Value") {
// Do Statement A
} else {
// Do Statement B
}
DISCLAIMER: Not doing the general short circuit method.
Well, you could create a separate function to perform the lookup, especially if the query remains the same. So something like this: (pseudocode incoming)
private bool IsNullCheck(string objectName)
{
if (object["Object Name"] != null)
return false;
else
// statement B
}
if (!IsNullCheck("Object Name") && if(object["Object name"] == "Value") {
// stuffs
}
else
{
// Do Statement B
}
Or the like.

How to avoid a NullReferenceException

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();
}

How do I detect a null reference in C#?

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!

Categories

Resources