Why are three properties in DbParameterCollection abstract in reference assemblies but virtual otherwise?

Solution 1:

The reference assemblies are correct. In .NET Framework 4.5, these properties were abstract. They were changed to virtual in .NET Framework 4.5.1. It appears you've uncovered a documentation bug.

As you probably have already guessed, the difference between the two System.Data.dll assemblies you are observing is due to how .NET Framework separates reference assemblies and runtime assemblies. The reference assembly in C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll accurately reflects what would have been in the 4.5 runtime version of System.Data.dll. If you're able to get an old machine that hasn't yet upgraded to .NET Framework 4.5.1 (good luck), you'll find that runtime assembly in C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll has these properties as abstract. .NET Framework upgrades in-place. On a machine that has upgraded to .NET Framework 4.5.1 or newer, C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll has been replaced with the updated version (with virtual, not abstract, properties.)

As far as workarounds: compile for net451 instead, or implementing dummy methods are the best approaches. You could do other tricks to compile against a different version of System.Data.dll, but I wouldn't recommend it

I couldn't find official documentation on the API changes between .NET Framework 4.5 and 4.5.1 or an explanation of why this was changed, however, I found this comment from a member of the Entity Framework team: https://bugzilla.xamarin.com/show_bug.cgi?id=29167#c0.

The following (non-breaking) changes were made to the System.Data APIs in the .NET Framework 4.5.1 release....

The following member were added.

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

The following member were changed from abstract to virtual.

  • 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