Skip to content

Nullable annotations of the IMapper(base) #4296

Description

@Erythnul

Hi, hope you are well.

I've been playing around with the preview build (because of issues with the Include/IncludeBase being fixed there and not in the master) and found that in commit 7bd1b81 nullable annotations were enabled for the IMapper interfaces.
This is great, however, I feel the implementation could be smarter using some of the static analysis annotations.

Currently, using the preview package would generate loads of nullability warnings in my code. The code mainly uses the method

TDestination? Map<TDestination>(object? source);

This doesn't seem entirely correct to me, as I make sure that the type going in is not null in these cases and expect a non-null output.

Assumptions (based on my experience):

  • If the source is not null
    AND
  • The typeMap is well-configured
    THEN
    The output TDestination cannot be null.

if the typeMap is not well-configured I expect an exception to be thrown, correct?

So we could solve this here by using the following:

    [return: NotNullIfNotNull(nameof(source))]
    TDestination? Map<TDestination>(object? source);

For the generic variants I'm not sure what you would prefer. The commit made it into the following:

    TDestination? Map<TSource, TDestination>(TSource? source);
    TDestination? Map<TSource, TDestination>(TSource? source, TDestination? destination);

But then, if I use it like this:

        var list = new List<TDestination>();
        var value = JsonConvert.DeserializeObject<TSource>(jsonString);

        if(value != null)
        {
            var mapped = context.Mapper.Map<TSource, TDestination>(value);
            viewModels.Add(mapped);
        }

I will still get a nullability warning on the viewModels.Add(mapped).
Here, I personally would expect nullability to be governed by the nullability of the generic parameters in the signature of the method, like so:
TDestination Map<TSource, TDestination>(TSource source);

This would allow for usage like above without nullability warnings, and properly warn you if you are potentially sending a null value into the mapper where you do not intend it. You could also explicitly enable nullability for the mapper like so:

            var mapped = context.Mapper.Map<TSource?, TDestination?>(value);
            viewModels.Add(mapped);

Alternatively, NotNullIfNotNull could also help here, but feels less flexible to me.

I could go on, but you get the point. Of course, I am willing to open up a PR so we can discuss this further.

What do you think?

Kind regards.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions