Skip to content

NullReferenceException when mapping from multiple sources when one source is null #414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jkuek opened this issue Mar 22, 2022 · 4 comments · May be fixed by #788
Open

NullReferenceException when mapping from multiple sources when one source is null #414

jkuek opened this issue Mar 22, 2022 · 4 comments · May be fixed by #788

Comments

@jkuek
Copy link

jkuek commented Mar 22, 2022

I have 3 source items to map to a destination. There is a possibility the third item will be null.

I create a config as follows:

            var config = TypeAdapterConfig<(a, b, c), Output>.NewConfig()
                .Map(dest => dest, src => src.Item1)
                .Map(dest => dest, src => src.Item2)
                .Map(dest => dest.Application, src => src.Item3 == null ? (Application) null : new Application()
                {
                    Id = src.Item3.Id,
                    Name = src.Item3.Name
                })

My expectation was that a null value for Item3 should be handled and a null value returned for the Application property of the output.

When I run the mapping:
var result = (x, y, z)Adapt<Output>(config.Config);
when z is null, then a NullReferenceException is thrown.

Is this a bug?

@andrerav andrerav added the bug label Mar 23, 2022
@andrerav andrerav self-assigned this Mar 23, 2022
@andrerav
Copy link
Contributor

At first glance, this looks like a bug. I will attempt to reproduce this with a regression test and see if I can pinpoint the problem. Is it possible for you to post a stack trace, or relevant parts of a stack trace? Can you also confirm that you are using the latest version of Mapster?

@jkuek
Copy link
Author

jkuek commented Mar 24, 2022

I confirm this issue is occurring using the Mapster 7.3.0 Nuget package.

The behaviour when using a tuple with a single element matches my expectations. For instance:

source.Adapt<Dest>() returns null if source is null

(source).Adapt<Dest>() returns null if source is null

but when using multiple elements it throws an exception (even without a config specified)

(source1, source2).Adapt<Dest>() throws NullReferenceException if either source is null

I'm not sure what should happen if no config is specified, but certainly in my use-case I was expecting dest.Application to be null if src.Item3 is null

@0xSa9
Copy link

0xSa9 commented Apr 24, 2022

Yes! I have same problem with version 7.3.0

`config.ForType<(Pair?, Record?, Favorite?), PairDto>()

          .Map(dest => dest, src => src.Item1)

          .Map(dest => dest, src => src.Item2, srcCond => srcCond.Item2 != null)

          .Map(dest => dest, src => src.Item3, srcCond => srcCond.Item3 != null); `

@DocSvartz
Copy link

DocSvartz commented Apr 9, 2025

A class as a reference type can always have a Null value.
NullableExpressionVisitor only checked for the presence of NullableAttribute.

It seems to be related to how nullability is determined for reference Tuple and ValueType members

(a, b, c) it is ValueTuple and Item3 has NullableAttribute [Nullable((byte) 1)] == not-null;

when you use reference Tuple
Tuple<a, b, c> Item3 does not get NullableAttribute at all

Which gave a false negative when checked in InvokerModel.
Because of this, the Condition was shortened to:

new Application()
{
Id = src.Item3.Id,
Name = src.Item3.Name
})

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

Successfully merging a pull request may close this issue.

4 participants