Pourquoi trois propriétés de DbParameterCollection sont-elles abstraites dans les assemblys de référence mais virtuelles sinon?

Je déplace un projet de project.json au format csproj de nouveau style, et il inclut une classe dérivée de DbParameterCollection . Dans mon vrai projet, j’utilise le multi-ciblage, mais pour les besoins de cette question, il suffit de se soucier de net45 .

Le compilateur me dit que je dois remplacer trois propriétés que je n’avais pas auparavant:

  • IsFixedSize
  • IsReadOnly
  • IsSynchronized

Si vous suivez ces liens de documentation (qui sont pour .NET 4.5), vous verrez que toutes les propriétés sont virtuelles – pas abstraites. Si je construis le code en appelant simplement csc , tout va bien … c’est seulement lorsque j’utilise le .NET Core SDK que je rencontre le problème.

Voici un exemple de code pour reproduire le problème:

Fichier projet:

   net45   

Code C #:

 using System; using System.Collections; using System.Data.Common; public class DummyParameterCollection : DbParameterCollection { public override int Count => 0; public override object SyncRoot => null; public override void Remove(object value) {} public override void RemoveAt(int index) {} public override void RemoveAt(ssortingng parameterName) {} public override int Add(object value) => 0; public override void Insert(int index, object value) {} public override void AddRange(Array values) {} public override void Clear() {} public override bool Contains(object value) => false; public override bool Contains(ssortingng value) => false; public override void CopyTo(Array array, int index) {} public override int IndexOf(object value) => -1; public override int IndexOf(ssortingng parameterName) => -1; protected override DbParameter GetParameter(int index) => null; protected override DbParameter GetParameter(ssortingng parameterName) => null; protected override void SetParameter(int index, DbParameter value) {} protected override void SetParameter(ssortingng parameterName, DbParameter value) {} public override IEnumerator GetEnumerator() => null; } 

Les erreurs:

DummyParameterCollection.cs (5,14): erreur CS0534: ‘DummyParameterCollection’ n’implémente pas le membre abstrait hérité ‘DbParameterCollection.IsSynchronized.get’ [c: \ Users \ skeet \ Test \ ParameterCollection \ ParameterCollection.csproj]
DummyParameterCollection.cs (5,14): erreur CS0534: ‘DummyParameterCollection’ n’implémente pas le membre abstrait hérité ‘DbParameterCollection.IsFixedSize.get’ [c: \ Users \ skeet \ Test \ ParameterCollection \ ParameterCollection.csproj]
DummyParameterCollection.cs (5,14): erreur CS0534: ‘DummyParameterCollection’ n’implémente pas le membre abstrait hérité ‘DbParameterCollection.IsReadOnly.get’ [c: \ Users \ skeet \ Test \ ParameterCollection \ ParameterCollection.csproj]

Je crois que je connais la cause immédiate du problème, mais pas les raisons pour lesquelles c’est comme ça ou la meilleure solution.

Il semble que le SDK .NET Core (et VS2017 lorsqu’il est chargé dans ce projet) utilise les assemblys de référence. Si j’ouvre C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll dans Reflector, cela montre également que les propriétés sont abstraites. Considérant que si j’ouvre c:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll , cela montre les propriétés comme étant virtuelles.

Je peux contourner ce problème en écrasant les propriétés et en renvoyant simplement la valeur false à chacune d’elles – mais est-ce la meilleure façon de gérer cette situation? Au-delà, y a-t-il une bonne raison pour laquelle les assemblys de référence ne correspondent pas aux assemblages réels (et à la documentation) dans ce cas? Je m’attendrais à ce que les assemblys de référence soient générés automatiquement, il est donc étrange que certaines choses soient incorrectes comme ceci …

Les assemblages de référence sont corrects. Dans .NET Framework 4.5, ces propriétés étaient abstract . Ils ont été changés en virtual dans .NET Framework 4.5.1. Il semble que vous ayez découvert un bug de documentation.

Comme vous l’avez probablement deviné, la différence entre les deux assemblys System.Data.dll que vous observez est due à la manière dont .NET Framework sépare les assemblys de référence et les assemblys d’exécution. L’assembly de référence dans C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll reflète fidèlement ce qui aurait été dans la version 4.5 de runtime de System.Data.dll . Si vous pouvez obtenir une ancienne machine qui n’a pas encore été mise à niveau vers .NET Framework 4.5.1 (bonne chance), vous trouverez cet assembly d’exécution dans C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll a ces propriétés en tant que abstract . Mise à niveau de .NET Framework sur place. Sur une machine qui a été mise à niveau vers .NET Framework 4.5.1 ou une version ultérieure, C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll a été remplacé par la version mise à jour (avec virtual , non abstract , Propriétés.)

En ce qui concerne les solutions de contournement: comstackz pour net451 place ou implémentez des méthodes factices sont les meilleures approches. Vous pouvez faire d’autres astuces pour comstackr avec une version différente de System.Data.dll, mais je ne le recommanderais pas

Je n’ai pas pu trouver de documentation officielle sur les modifications de l’API entre .NET Framework 4.5 et 4.5.1 ou une explication de la raison de cette modification. Cependant, j’ai trouvé ce commentaire d’un membre de l’équipe Entity Framework: https: // bugzilla. xamarin.com/show_bug.cgi?id=29167#c0 .

Les modifications suivantes (non interrompues) ont été apscopes aux API System.Data dans la version .NET Framework 4.5.1 ….

Les membres suivants ont été ajoutés.

  • System.Data.Common.DbParameter.Precision
  • System.Data.Common.DbParameter.Scale
  • System.Data.SqlClient.SqlConnectionSsortingngBuilder.ConnectRetryCount
  • System.Data.SqlClient.SqlConnectionSsortingngBuilder.ConnectRetryInterval

Les membres suivants sont passés de l’abstrait au virtuel.

  • System.Data.Common.DbDataReader.Close
  • System.Data.Common.DbDataReader.GetSchemaTable
  • System.Data.Common.DbParameter.SourceVersion
  • System.Data.Common.DbParameterCollection.IsFixedSize
  • System.Data.Common.DbParameterCollection.IsReadOnly
  • System.Data.Common.DbParameterCollection.IsSynchronized