Juste une explication de pourquoi cette exception est levée. Vous pouvez reproduire l'exception avec cet exemple d'application Windows Forms. Commencez par ajouter un paramètre nommé "Setting" de type StringCollection. Cliquez sur les points dans la colonne Valeur et entrez quelques chaînes. Faites ressembler le code de classe de formulaire comme ceci:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
protected override void OnFormClosing(FormClosingEventArgs e) {
Properties.Settings.Default.Setting[0] = DateTime.Now.ToString();
Properties.Settings.Default.Save();
base.OnFormClosing(e);
}
}
Déboguer + Exceptions, cochez la case Thrown pour les exceptions CLR. Exécutez le formulaire et fermez-le, le débogueur s'arrêtera lorsque l'exception est levée. Le haut de la pile d'appel ressemble à ceci:
mscorlib.dll!System.Reflection.Assembly.nLoad(System.Reflection.AssemblyName fileName, string codeBase, System.Security.Policy.Evidence assemblySecurity, System.Reflection.Assembly locationHint, ref System.Threading.StackCrawlMark stackMark, bool throwOnFileNotFound, bool forIntrospection) + 0x2c bytes
mscorlib.dll!System.Reflection.Assembly.InternalLoad(System.Reflection.AssemblyName assemblyRef, System.Security.Policy.Evidence assemblySecurity, ref System.Threading.StackCrawlMark stackMark, bool forIntrospection) + 0x80 bytes
mscorlib.dll!System.Reflection.Assembly.Load(System.Reflection.AssemblyName assemblyRef) + 0x1d bytes
System.Xml.dll!System.Xml.Serialization.TempAssembly.LoadGeneratedAssembly(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null, out System.Xml.Serialization.XmlSerializerImplementation contract = null) + 0xcd bytes
System.Xml.dll!System.Xml.Serialization.XmlSerializer.XmlSerializer(System.Type type = {Name = "StringCollection" FullName = "System.Collections.Specialized.StringCollection"}, string defaultNamespace = null) + 0x105 bytes
Vous pouvez voir la chasse de classe XmlSerializer pour un ensemble qui contient le sérialiseur XML pour la classe StringCollection. La méthode LoadGeneratedAssembly ressemble à ceci avec les trépans enlevés:
internal static Assembly LoadGeneratedAssembly(Type type, string defaultNamespace, out XmlSerializerImplementation contract)
{
...
AssemblyName parent = GetName(type.Assembly, true);
partialName = Compiler.GetTempAssemblyName(parent, defaultNamespace);
parent.Name = partialName;
parent.CodeBase = null;
parent.CultureInfo = CultureInfo.InvariantCulture;
try
{
serializer = Assembly.Load(parent); // <=== here
}
catch (Exception exception)
{
...
}
....
}
Et Compiler.GetTempAssemblyName():
internal static string GetTempAssemblyName(AssemblyName parent, string ns)
{
return (parent.Name + ".XmlSerializers" + (((ns == null) || (ns.Length == 0)) ? "" : ("." + ns.GetHashCode())));
}
Ce GetTempAssemblyName est le malfaiteur dans ce cas. La classe StringCollection vit dans l'assembly System.dll, la méthode génère le nom "System.XmlSerializers". Cette méthode est conçue pour trouver l'assembly pour vos propres classes, celui généré par Sgen.exe. Comme WindowsApplication1.XmlSerializers.dll pour votre exemple de programme. Mais StringCollection est une classe dans le .NET Framework, le nom de l'assembly qu'il génère n'est pas valide. Il n'y a pas réellement de "System.XmlSerializers".dll "assembly dans le cadre
Les rapports d'évaluation de ce comportement sur connect.microsoft.com ont tous été fermés avec" By Design ", les concepteurs d'origine ont estimé que le coût de la prévention de l'exception était trop élevé et ont décidé de L'exception est en effet attrapée, mais vous l'avez vu parce que vous avez activé la case à cocher Thrown dans la boîte de dialogue Debug + Exceptions
Le code de sérialisation Xml se comporte différemment Il aurait été assez facile pour eux de filtrer simplement les types dans l'assembly System.dll, mais c'est une bataille potentiellement interminable, il y a beaucoup plus d'assemblages dans le framework. classe pour stocker le paramètre à la place d'utiliser un StringCollection.
Merci pour l'explication détaillée. J'essaie d'éviter d'utiliser StringCollection dans le futur. Dommage c'est "par conception". – testalino
Là vous allez :) – testalino
Brillante réponse encore une fois ... – MoonKnight