Bonjour,

Pour les besoins d'un projet, j'ai dû écrire une petite lib permettant d'utiliser un IDataReader basé sur un chemin XPath dans un fichier XML plutôt que le résultat d'une requête SQL dans une base de données.

Outre les aspects métaphysiques permettant de déterminer le bien du mal d'une telle pratique, je me heurte à des messages d'avertissement lors de la compilation que je n'arrive pas à résoudre dans mon implémentation de IDbConnection.

Je suis avec .NET 9.0 et C# 13.0 avec l'option "Nullable = enable".
Code xml : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

Voici le code :
Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System.Data;
using System.Xml;
 
namespace AZToolBox.Xml
{
    public class XmlConnection : IDbConnection
    {
        private bool open = false;
        internal XmlReader? Reader;
 
        private bool disposedValue;
 
        public XmlConnection() : this(null) 
        {
        }
 
        public XmlConnection(string? connectionString)
        {
            if (connectionString is null)
            {
                ConnectionString = string.Empty;
            }
            else
            {
                ConnectionString = connectionString;
            }
        }
 
        public string ConnectionString { get; set; }
 
        public int ConnectionTimeout => throw new NotImplementedException();
 
        public string Database => throw new NotImplementedException();
 
        public ConnectionState State
        {
            get
            {
                if (open)
                {
                    return ConnectionState.Open;
                }
                else
                {
                    return ConnectionState.Closed;
                }
            }
        }
 
        public IDbTransaction BeginTransaction()
        {
            throw new NotImplementedException();
        }
 
        public IDbTransaction BeginTransaction(IsolationLevel il)
        {
            throw new NotImplementedException();
        }
 
        public void ChangeDatabase(string databaseName)
        {
            throw new NotImplementedException();
        }
 
        public void Close()
        {
            if (Reader is not null)
            {
                Reader.Close();
                Reader.Dispose();
                Reader = null;
            }
            open = false;
        }
 
        public IDbCommand CreateCommand()
        {
            return new XmlCommand(this);
        }
 
        public void Open()
        {
            Reader = XmlReader.Create(ConnectionString);
            open = true;
        }
 
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // TODO: supprimer l'état managé (objets managés)
                    Close();
                }
 
                // TODO: libérer les ressources non managées (objets non managés) et substituer le finaliseur
                // TODO: affecter aux grands champs une valeur null
                disposedValue = true;
            }
        }
 
        // // TODO: substituer le finaliseur uniquement si 'Dispose(bool disposing)' a du code pour libérer les ressources non managées
        // ~XmlConnection()
        // {
        //     // Ne changez pas ce code. Placez le code de nettoyage dans la méthode 'Dispose(bool disposing)'
        //     Dispose(disposing: false);
        // }
 
        public void Dispose()
        {
            // Ne changez pas ce code. Placez le code de nettoyage dans la méthode 'Dispose(bool disposing)'
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }
    }
}

Et les avertissements :
Ligne 29, sur le set de ConnectionString, j'ai un CS8767 :
La nullabilité des types référence dans le type du paramètre 'value' de 'void XmlConnection.ConnectionString.set' ne correspond pas au membre implémenté implicitement 'void IDbConnection.ConnectionString.set' (probablement en raison des attributs de nullabilité).
Si je transforme ConnectionString en string? j'ai cette fois un autre numéro d'erreur, inverse, sur les get.

J'ai tenté de passer par un attribut privé et des tests explicites de nullabilité, à la fois avec une propriété string et string?, mais ça ne change rien.

J'ai l'impression que ça vient du fait que IDbConnection a été compilé en mode "string peut être null" alors que mon projet, lui, l'interdit.

J'ai les mêmes soucis sur mes implémentations de IDbCommand.CommandText et IDataReader.

Ça n'empêche pas de compiler, mais un code avec des warnings j'aime pas ça.
Une idée pour résoudre ?