targetframework standard netstandard2 netcoreapp2 net library framework deploy clases biblioteca c# .net-core assemblies

c# - standard - targetframework netcoreapp2 0</ targetframework



¿Por qué hay tres propiedades en DbParameterCollection abstractas en ensamblajes de referencia pero virtuales de otra manera? (1)

Estoy moviendo un proyecto de project.json al formato csproj de nuevo estilo, e incluye una clase derivada de DbParameterCollection . En mi proyecto real estoy usando la orientación múltiple, pero a los fines de esta pregunta solo necesitamos preocuparnos por net45 .

El compilador me dice que tengo que anular tres propiedades que no tenía antes:

Si sigue esos enlaces de documentación (que son para .NET 4.5) verá que todas las propiedades son virtuales , no abstractas. Si construyo el código simplemente llamando a csc , todo está bien ... es solo cuando uso .NET Core SDK que me encuentro con el problema.

Aquí hay un código de muestra para reproducir el problema:

Archivo de proyecto:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net45</TargetFramework> </PropertyGroup> </Project>

Código 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(string 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(string value) => false; public override void CopyTo(Array array, int index) {} public override int IndexOf(object value) => -1; public override int IndexOf(string parameterName) => -1; protected override DbParameter GetParameter(int index) => null; protected override DbParameter GetParameter(string parameterName) => null; protected override void SetParameter(int index, DbParameter value) {} protected override void SetParameter(string parameterName, DbParameter value) {} public override IEnumerator GetEnumerator() => null; }

Errores:

DummyParameterCollection.cs (5,14): error CS0534: ''DummyParameterCollection'' no implementa el miembro abstracto heredado ''DbParameterCollection.IsSynchronized.get'' [c: / Users / skeet / Test / ParameterCollection / ParameterCollection.csproj]
DummyParameterCollection.cs (5,14): error CS0534: ''DummyParameterCollection'' no implementa el miembro abstracto heredado ''DbParameterCollection.IsFixedSize.get'' [c: / Users / skeet / Test / ParameterCollection / ParameterCollection.csproj]
DummyParameterCollection.cs (5,14): error CS0534: ''DummyParameterCollection'' no implementa el miembro abstracto heredado ''DbParameterCollection.IsReadOnly.get'' [c: / Users / skeet / Test / ParameterCollection / ParameterCollection.csproj]

Creo que sé la causa inmediata del problema, pero no las razones por las que es así, o la mejor solución.

Parece que .NET Core SDK (y VS2017 cuando se carga este proyecto) usa los ensamblados de referencia. Si abro C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.5/System.Data.dll en Reflector, eso también muestra las propiedades como abstractas. Mientras que si abro c:/Windows/Microsoft.NET/Framework/v4.0.30319/System.Data.dll , eso muestra las propiedades como virtuales.

Puedo evitar esto al anular las propiedades y simplemente devolver false de todas ellas, pero ¿es esa la mejor manera de manejar esta situación? Más allá de eso, ¿hay alguna buena razón por la cual los ensambles de referencia no coinciden con los ensamblajes reales (y la documentación) en este caso? Esperaría que los ensambles de referencia se autogeneren, por lo que es extraño que algunas cosas sean incorrectas como esta ...


Los ensambles de referencia son correctos. En .NET Framework 4.5, estas propiedades eran abstract . Se cambiaron a virtual en .NET Framework 4.5.1. Parece que has descubierto un error de documentación.

Como probablemente ya haya adivinado, la diferencia entre los dos ensamblados System.Data.dll que está observando se debe a cómo .NET Framework separa los ensamblajes de referencia y los ensamblajes de tiempo de ejecución. El ensamblado de referencia en C:/Program Files (x86)/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.5/System.Data.dll refleja con precisión lo que habría sido en la versión 4.5 en tiempo de ejecución de System.Data.dll . Si puede obtener una máquina antigua que aún no se ha actualizado a .NET Framework 4.5.1 (buena suerte), encontrará ese ensamblado en tiempo de ejecución en C:/Windows/Microsoft.NET/Framework/v4.0.30319/System.Data.dll tiene estas propiedades como abstract . .NET Framework se actualiza en el lugar. En una máquina que se ha actualizado a .NET Framework 4.5.1 o posterior, C:/Windows/Microsoft.NET/Framework/v4.0.30319/System.Data.dll se ha reemplazado por la versión actualizada (con virtual , no abstract , propiedades.)

En cuanto a las soluciones: compilar para net451 en net451 lugar, o implementar métodos ficticios son los mejores enfoques. Podría hacer otros trucos para compilar en una versión diferente de System.Data.dll, pero no lo recomendaría

No pude encontrar documentación oficial sobre los cambios de API entre .NET Framework 4.5 y 4.5.1 o una explicación de por qué esto se cambió, sin embargo, encontré este comentario de un miembro del equipo de Entity Framework: https://bugzilla.xamarin.com/show_bug.cgi?id=29167#c0 .

Los siguientes cambios (sin interrupción) se realizaron en las API de System.Data en la versión .NET Framework 4.5.1 ...

El siguiente miembro fue agregado.

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

El siguiente miembro fue cambiado de abstracto a 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