Роу Вілсон Фредеріск Холм
Роу Вілсон Фредеріск Холм
CC#
Created by Роу Вілсон Фредеріск Холм on 3/29/2025 in #help
Warning about Trimmers and XmlSerializers
My library uses a trimmer to handle complex XML. But when I turned on code trimming for it, it showed warning IL2026: [...] Members from serialized types may be trimmed if not referenced directly., the code looked like this:
[Serializable]
[XmlType(nameof(MyData))]
public class Foo {
public Double Number { get; set; }
}

[Serializable]
[XmlType(nameof(MyData))]
[XmlRoot()]
public class MyData {
public Foo Foo { get; set; }
public Int32 Bar { get; set; }
}

public static class MyDataXmlWrapper {
private static readonly XmlSerializer serializer = new(typeof(MyData)); // IL2026
public static MyData ReadMyDataFromFile(FileInfo file) {
using FileStream xmlStream = file.OpenRead();
using XmlReader reader = XmlReader.Create(xmlStream);
MyData data = (MyData)serializer.Deserialize(reader)!; // IL2026
return data;
}
// ...
}
[Serializable]
[XmlType(nameof(MyData))]
public class Foo {
public Double Number { get; set; }
}

[Serializable]
[XmlType(nameof(MyData))]
[XmlRoot()]
public class MyData {
public Foo Foo { get; set; }
public Int32 Bar { get; set; }
}

public static class MyDataXmlWrapper {
private static readonly XmlSerializer serializer = new(typeof(MyData)); // IL2026
public static MyData ReadMyDataFromFile(FileInfo file) {
using FileStream xmlStream = file.OpenRead();
using XmlReader reader = XmlReader.Create(xmlStream);
MyData data = (MyData)serializer.Deserialize(reader)!; // IL2026
return data;
}
// ...
}
I looked everywhere but didn't find any direct solutions, and the .NET XML serialization code seems to have been out of date for a long time, and lacks many features to circumvent reflection mechanisms, such as Source Generation, compared to JSON. I don't want to overcomplicate the code, so my own guess at a solution is to create a new class and use the DynamicalAccessedMembersAttribute to prevent the trimmer from trimming key class fields and properties:
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", Justification = "the constructor will keep all members of the target type.")]
private class MyXmlSerializer : XmlSerializer {
public MyXmlSerializer([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicPtoperties /* and others members if they are necessary. */)] Type type) : base(type) { }
public new Object Deserialize(XmlReader reader) => base.Deserialize(reader)!;
}

// and
private static readonly MyXmlSerializer serializer = new(typeof(MyData));
[UnconditionalSuppressMessage("AssemblyLoadTrimming", "IL2026:RequiresUnreferencedCode", Justification = "the constructor will keep all members of the target type.")]
private class MyXmlSerializer : XmlSerializer {
public MyXmlSerializer([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicPtoperties /* and others members if they are necessary. */)] Type type) : base(type) { }
public new Object Deserialize(XmlReader reader) => base.Deserialize(reader)!;
}

// and
private static readonly MyXmlSerializer serializer = new(typeof(MyData));
Is this correct? Are there any other possible correct options I have?
3 replies