Search code examples
c#automapper

AutoMapping: Dereference of a possibly null reference? Null-conditional operator doesn't work with AutoMapping


I'm using AutoMapper for class A and B. The project is a .Net core project with <Nullable>enabled</Nullable>.

public class A 
{
    public ClassX? X { get; set; } // ClassX is a custom class with the property of Value.
    //.... 
}

public class B 
{
    public string? X { get; set; } 
   // ....
}

In the following mapping code

public void Mapping(Profile profile)
{
    // ....

    _ = profile?.CreateMap<A, B>()
        .ForMember(d => d.X, o => o.MapFrom(s => s.X.Value)); // warning on s.X
}

it has the following warning on s.X:

Warning CS8602 Dereference of a possibly null reference.

How to get rid of the warning without using #pragma warning disable CS8602?

I tried to change o.MapFrom(s => s.X.Value) to o.MapFrom(s => s.X?.Value) using Null-conditional. But it got the following error on s.X?.Value.

Error CS8072 An expression tree lambda may not contain a null propagating operator


Solution

  • Since MapFrom accepts an Expression<> and not a Func<>, you cannot use the Null-conditional operator. This is not a limitation of AutoMapper, it is a limitation of the expression trees in the System.Linq.Expressions namespace and of the C# compiler.

    However, you can use a ternary operator:

    _ = profile?.CreateMap<A, B>()
        .ForMember(d => d.X, o => o.MapFrom(s => s.X == null ? null : s.X.Value));
    

    According to your declaration, the property X is nullable. Therefore, you must ensure that it will not be dereferenced if it is null.

    (According to @Attersson) If you want to assign a different value in the null case, you can use the null-coalescing operator in conjunction with the ternary operator.

    (s.X == null ? someDefaultValue : s.X.Value)
    
    // e.g for string
    (s.Text == null ? String.Empty : s.Text)