Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assert Variable is not Null

Tags:

c#

kotlin

I have a Variable with type DateTime?

In a Function I check it for being null and want to use it afterwards without always having to ?. every call. In e.g. Kotlin the IDE recognizes a check like that and asserts that the variable cannot be null afterwards. Is there a way to do this in C#?

DateTime? BFreigabe = getDateTime();
if (BFreigabe == null) return false;
TimeSpan span = BFreigabe - DateTime.Now; 
//Shows Error because it.BFreigabe has the type DateTime?, even though it can't be null

Edit:

When using

TimeSpan span = BFreigabe.Value - DateTime.Now;

instead it works in this case because .Value doesn't have nullsafety at all. However, considering that this would compile even without the null check and just produce an error, the general question still remains. How can one persuade C# that a former nullable variable isn't nullable any more?

Edit 2

Casting DateTime on the Variable works.

TimeSpan span = (DateTime)BFreigabe - DateTime.Now;

Still not as safe as in Kotlin, but similar enough.

like image 800
Looki Avatar asked Jul 26 '17 12:07

Looki


1 Answers

If you have the previous check, you can access the value. Nullable types always have two properties: HasValue and Value.

You could either cast to DateTime (Without the ?) or use the value property.

DateTime? BFreigabe = getDateTime();
if (!BFreigabe.HasValue == null) 
    return false;

TimeSpan span = BFreigabe.Value - DateTime.Now;

Or store the nullable variable in a non nullable variable:

DateTime? BFreigabe = getDateTime();
if (BFreigabe.HasValue == null) 
{
    DateTime neverNull = BFreigabe.Value;
    TimeSpan span = neverNull  - DateTime.Now;
}

This will get full editor support and guarantee that there is no NullReferenceExcpetion.

EDIT: Because your question states Assert. Assert usually means that we will throw an exception if the state is invalid.

In this case, omit the check for nullness. If you access var.Value while var is null, this will throw a NullReferenceException. This moves the responsibility to the caller.

Another option would be to not use the nullable variable. Either by converting it (see the second listing) or by not accepting Nullable types as a parameter.

function TimeSpan Calc(DateTime time)
{
    // here we know for sure, that time is never null
}
like image 117
Iqon Avatar answered Sep 28 '22 05:09

Iqon