Simply null check + property access - c#

Is there an operator to simplify this operation in C# to avoid null pointer exceptions?
obj == null ? null : obj.Property;
Something like
obj?.Property;
I really want to get rid of NullReferenceExeptions

As #canton7 said, you answered your own question.
The ?. operator actually exists in C#
Here's a small example showing how it prevents the NullReferenceException
public class Program
{
public static void Main(string[] args)
{
List<string> list = GetList();
Console.WriteLine($"{list?.Count}");
Console.ReadKey();
}
public static List<string> GetList()
{
return null;
}
}

Related

When can a null check throw a NullReferenceException

I know this might seem impossible at first and it seemed that way to me at first as well, but recently I have seen exactly this kind of code throw a NullReferenceException, so it is definitely possible.
Unfortunately, there are pretty much no results on Google that explain when code like foo == null can throw a NRE, which can make it difficult to debug and understand why it happened. So in the interest of documenting the possible ways this seemingly bizarre occurrence could happen.
In what ways can this code foo == null throw a NullReferenceException?
in C# you can overload operators to add custom logic on some comparison like this. For example:
class Test
{
public string SomeProp { get; set; }
public static bool operator ==(Test test1, Test test2)
{
return test1.SomeProp == test2.SomeProp;
}
public static bool operator !=(Test test1, Test test2)
{
return !(test1 == test2);
}
}
then this would produce a null reference exception:
Test test1 = null;
bool x = test1 == null;
One example is with getters:
class Program
{
static void Main(string[] args)
{
new Example().Test();
}
}
class Example
{
private object foo
{
get => throw new NullReferenceException();
}
public void Test()
{
Console.WriteLine(foo == null);
}
}
This code will produce a NullReferenceException.
While quite esoteric, it is possible to cause this type of behavior via custom implementations of DynamicMetaObject. This would be a rare but interesting example of where this could occur:
void Main()
{
dynamic foo = new TestDynamicMetaObjectProvider();
object foo2 = 0;
Console.WriteLine(foo == foo2);
}
public class TestDynamicMetaObjectProvider : IDynamicMetaObjectProvider
{
public DynamicMetaObject GetMetaObject(Expression parameter)
{
return new TestMetaObject(parameter, BindingRestrictions.Empty, this);
}
}
public class TestMetaObject : DynamicMetaObject
{
public TestMetaObject(Expression expression, BindingRestrictions restrictions)
: base(expression, restrictions)
{
}
public TestMetaObject(Expression expression, BindingRestrictions restrictions, object value)
: base(expression, restrictions, value)
{
}
public override DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
{
// note it doesn't have to be an explicit throw. Any improper property
// access could bubble a NullReferenceException depending on the
// custom implementation.
throw new NullReferenceException();
}
}
Not literally your code, but awaiting a null task will also throw:
public class Program
{
public static async Task Main()
{
var s = ReadStringAsync();
if (await s == null)
{
Console.WriteLine("s is null");
}
}
// instead of Task.FromResult<string>(null);
private static Task<string> ReadStringAsync() => null;
}
Do note however that the debugger can get the location of throwing statements wrong. It might show the exception thrown at the equality check, while it occurs at earlier code.
foo == null does indeed to operator overload resolution, and the operator in question didn't handle being passed a null. We are starting to consider writing foo == null obsolete and preferring (taking a page from Visual Basic) foo is null or !(foo is null) which is soon to be full is not null to explicitly inline a null pointer check.
Fix your operator== implemenation. It shouldn't throw, but it is.

C# null check chain in method call

I suppose method call chain below.
void DoSomething()
{
ObjectA a = CreateA();
if (a != null)
{
a.Foo();
}
}
ObjectA CreateA()
{
ObjectB b = CreateB();
if (b != null)
{
ObjectA a = b.ToA();
return a;
}
return null;
}
If method call depth get deeper, null checking will be more overlapped.
Is there any good solution for this?
Modified
I changed example code. It can't solve my problem that change CreateA to constructor.
The problem is only unnecessary null check chaining overlapping.
void SetImage()
{
UISprite image = GetSprite();
if (image != null)
{
image.spriteName = "hat";
}
}
UISprite GetSprite()
{
UISprite image = GetComponent<UISprite>();
if (image != null)
{
image.width = 100;
image.height = 100;
return image;
}
return null;
}
Starting with C# 6.0 you can use Null-Conditional Operator, which lets you make null-checking implicitly:
var result = possiblyNull?.MethodThatCanReturnNull()?.SomeProperty;
This construct will produce a null result if any element in the chain produces null.
You can do
void DoSomething()
{
CreateA()?.Foo();
}
ObjectA CreateA()
{
return CreateB()?.ToA();
}
Your other approach if you can't use C# 6, is don't return nulls, use null objects that way you never have to deal with null checking ( but you can still check if something is the null object )
If you are using C# 6.0 or higher, you got an easy solution with Null conditional operators for this issue.
see this link
https://msdn.microsoft.com/en-au/library/dn986595.aspx?f=255&MSPPError=-2147217396&cs-save-lang=1&cs-lang=csharp#code-snippet-1
So, assuming you (or someone else) can't use the null-conditional operator, is there a good reason to be using this pattern of methods creating objects instead of constructors creating the objects? Constructors are guaranteed not to return null.
It looks like you have some conversion or nested object heirarchy, but no inheritance heirarchy where you could just fall back on polymorphism. Maybe a tool like AutoMapper could be useful to encode these ToX() methods in a consistent manner?
I'm not sure how "nested" this would be. Your CreateB() method is going to look exactly like your CreateA() code. You're not going to end up with a "pyramid," just a lot of identical methods.
ObjectB CreateB()
{
ObjectC c = CreateC();
if (c != null)
{
ObjectB b = c.ToB();
return b;
}
return null;
}
Most of the time, you're doing this in an environment where you don't control all the classes. In that case, writing your own conversion functions or AutoMapper (really, worth the time) is the best approach. But, if you own the class hierarchy you might implement an abstract class that will do most of the heavy lifting for you. But honestly, I would only write something like this if I had a really good reason (something more than I just wanted to fuck with people). I include this to demonstrate how much simpler life is if you just use a constructor, which is guaranteed not to return null;
public abstract class MyAbstractObject<Tobj> where TObj: MyAbstractObject, new()
{
public static MyAbstractObject CreateObject()
{
Tobj subOb = new TObj();
MyAbstractObject parent = subOb.ToObject();
return parent;
}
public virtual TObj ToObject()
{
return CreateObject();
}
}
public class ObjectD : MyAbstractObject<ObjectC> { }
public class ObjectC : MyAbstractObject<ObjectB> { }
public class ObjectB : MyAbstractObject<ObjectA> { }
public class ObjectA : MyAbstractObject<ObjectA>
{
public override TObj ToObject()
{
return this;
}
}
static void Main()
{
ObjectA a = ObjectD.CreateObject();
}

Does Any() extension method handle null values?

In the below program, (!testlist.Any()) throws an argument null exception. Doesn't Any() extension method by default handle null values ?
What is the right approach for this ? Should a null check be added before Any() when List<int> is used as a parameter in a method ?
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello, world!");
foo(null);
}
public static void foo(List<int> testlist)
{
if (!testlist.Any())
{
Console.WriteLine("testlist is empty!");
}
}
}
Should a null check be added before Any() when List is used as a
parameter in a method ?
Yes, that's the right approach. The method should fail fast with a meaningful message.
public static void foo(List<int> testlist)
{
if(testlist == null)
throw new ArgumentNullException(nameof(testlist), $"{nameof(testlist)} must not be null");
if (!testlist.Any())
{
Console.WriteLine("testlist is empty!");
}
}
Of course Enumerable.Any does not handle this for you. It might be a bug that null was passed to this method or it might be a viable option. Only you know.
The exception is also documented:
"ArgumentNullException: source is null."
If you don't want to throw it but you want to accept null, just handle this case:
if(testlist == null || !testlist.Any())
{
Console.WriteLine("testlist is null or empty!");
}
else ....

Is there a null handler to string method at c#

I am able to assign a variable like below:
if (Session["myVariable"] != null)
{
string variAble = Session["myVariable"].ToString();
}
Is there a method which checks whether an object is null or not and then assign if it is not null?
string variAble = Session["myVariable"] ?? "";
EDIT A slightly more robust form, as suggested by #hatchet, is:
string variAble = (Session["myVariable"] ?? "").ToString();
While this isn't anything new, you can use the conditional operator to potentially simplify this:
string variable = Session["myVariable"] != null ? Session["myVariable"].ToString() : "Fallback";
You could write an extension method, as those still work with null objects.
public static class StringExtensions
{
public static String ToNullString(this object o)
{
return o == null ? "" : o.ToString();
}
}
I would consider it poor form though - it'll be confusing to whoever will be supporting the code after you, or even to you a few months down the track. It's probably better to just do the null check.

Question about checking for null values

I just got into a debate with one of my coworkers about checking for null values.
He SWEARS that "in certain situations" the code below would give him a null value exception:
string test = null;
if(test == null) //error here
{
}
but that if changed the code to this there would be no error:
string test = null;
if(null == test) //NO error here
{
}
I told him there was no way this could happen but he swears it fixed his code. Is there any possible situation where the above change could fix an error?
Not with string, no. You could do so with a badly written == overload though:
using System;
public class NaughtyType
{
public override int GetHashCode()
{
return 0;
}
public override bool Equals(object other)
{
return true;
}
public static bool operator ==(NaughtyType first, NaughtyType second)
{
return first.Equals(second);
}
public static bool operator !=(NaughtyType first, NaughtyType second)
{
return !first.Equals(second);
}
}
public class Test
{
static void Main()
{
NaughtyType nt = null;
if (nt == null)
{
Console.WriteLine("Hmm...");
}
}
}
Of course, if you changed the equality operator to this:
public static bool operator ==(NaughtyType first, NaughtyType second)
{
return second.Equals(first);
}
then your colleagues code would fail, but yours wouldn't! Basically if you overload operators properly - or use types which don't overload operators - this isn't a problem. If your colleague keeps claiming he's run into it, ask him to reproduce it. He certainly shouldn't be asking you to reduce readability (I believe most people find the first form more readable) on the basis of something he can't demonstrate.
I think this is a left-over from a 'best practice' in C/C++, because using '=' instead of '==' is an easy to make mistake:
if(test = null) // C compiler Warns, but evaluates always to false
if(null = test) // C compiler error, null cannot be assigned to
In C#, they both produce an error.
You're right. If he can reproduce this without an overloaded == operator, invite him to post it here.
The test of if (test == null) if test is a string is valid and will never give an exception. Both tests are also essentially exactly the same.

Categories

Resources