Description
Environment
.NET 7.0.102, Android workload 33.0.26/7.0.100
Scenario
I encountered the issue similar to what's described here: JamesNK/Newtonsoft.Json#2802, so I'll just use it as an example.
So there is an issue with the following code if you run it on a trimmed Android app:
var tuple = new Tuple<decimal, string>(1, "one");
var json = JsonConvert.SerializeObject(tuple);
It throws an exception which is clearly a result of the trimming process:
Newtonsoft.Json.JsonSerializationException: A member with the name '' already exists on 'System.Tuple`2[System.Decimal,System.String]'. Use the JsonPropertyAttribute to specify another name.
...
I would expect this to be solved by adding the System.Private.CoreLib
assembly into the trimmer exclusions by adding the following into the .csproj
:
<ItemGroup>
<TrimmerRootDescriptor Include="MyRoots.xml" />
</ItemGroup>
... and the following into the MyRoots.xml
file:
<linker>
<assembly fullname = "System.Private.CoreLib" preserve="all" />
</linker>
Unfortunatelly, this doesn't fix the issue, although it definitely changes things for the System.Private.CoreLib
- I can see that the resulting assembly size is now larger, which means the configuration has been applied.
Workarounds
- Setting
<IsTrimmable>false</IsTrimmable>
for the assembly as described here: Android .net6 project throw exception when serilaize Tuple in Release mode (v13.0.2) JamesNK/Newtonsoft.Json#2802 (comment) - Adding
<TrimmerRootAssembly Include="System.Private.CoreLib" />
into the.csproj
I went with the latter for now since it's more neat, but to be honest, I don't understand why does it not work in the same way as TrimmerRootDescriptor
. In my mind it's supposed to be fully equivalent to the preserve="all"
attribute.
Question
So is it a configuration bug or is this behavior by design? And which way should one choose to exclude something from the trimming process completely after all?