Home > Software engineering >  Convert a nullable to a non-nullable variable in C#/dotnet
Convert a nullable to a non-nullable variable in C#/dotnet

Time:06-21

This sounds trivial but I am having challenge. I cannot convert a nullable to a non-nullable value:

if (caseObj.SyncDate != null)
    caseDTO.SyncDate = DateTimeHelper.getFormattedDateTime(caseObj.SyncDate);

Where my caseObj.SyncDate is defined as:

public DateTimeOffset? SyncDate {get;set;}

And my getFormattedDateTime is:

    public static string getFormattedDateTime(DateTimeOffset dateTimeOffset) {

        string returnDate = null;

        if (dateTimeOffset != null) {
            returnDate = dateTimeOffset.ToString("yyyy-MM-dd HH:mm:ss.fffzzz", CultureInfo.InvariantCulture);
        }
        return returnDate;
    }

I read this and tried:

        if (caseObj.SyncDate != null)
            caseDTO.SyncDate = DateTimeHelper.getFormattedDateTime(caseObj.SyncDate!):

Which seems strange since I saw this link to Microsoft documentation which states:

Sometimes you must override a warning when you know a variable isn't null, but the compiler determines its null-state is maybe-null. You use the null-forgiving operator ! following a variable name to force the null-state to be not-null. For example, if you know the name variable isn't null but the compiler issues a warning, you can write the following code to override the compiler's analysis:

But that didn't seem to work. I have read this post (which I thought was focused enough) and this one for which the marked solution was not to convert from nullable to null.

I have tried this as well:

        if (caseObj.SyncDate != null) {
            DateTimeOffset dto = (DateTimeOffset) caseObj.SyncDate;
            caseDTO.SyncDate = DateTimeHelper.getFormattedDateTime(dto);
        }

But get this:

Argument 1: cannot convert from 'System.DateTimeOffset?' to 'System.DateTime'

Which is strange because I am not trying to convert from System.DateTimeOffset? to System.DateTime. I am trying to convert System.DateTimeOffset? to DateTimeOffset.

I'm running dotnet core on a Mac (version 6.0.201). There seem to be some long complicated answers, but I assume there is a simple way to do this that I'm missing.

CodePudding user response:

If I get you right - you might want something like this:

if (caseObj.SyncDate.HasValue)
    caseDTO.SyncDate = DateTimeHelper.getFormattedDateTime(caseObj.SyncDate.Value);

CodePudding user response:

By using pattern matching, you can write:

if (caseObj.SyncDate is { } syncDate) {
    caseDTO.SyncDate = DateTimeHelper.getFormattedDateTime(syncDate);
}

or

if (caseObj.SyncDate is DateTimeOffset syncDate) {
    caseDTO.SyncDate = DateTimeHelper.getFormattedDateTime(syncDate);
}

{ } is an empty property pattern which implicitly tests for not null. The result, a non-nullable DateTimeOffset is assigned to a new variable syncDate if the condition succeeds.

The second version uses a type pattern which tests whether the value is a DateTimeOffset. It only succeeds if the value is not null. null has no type and never satisfies a type test.

The nice thing about a pattern matching approach is that it does three things:

  1. it tests a condition
  2. it creates a local variable
  3. it casts the input value to the result type (DateTimeOffset? to DateTimeOffset in this case).
  • Related