¿Por qué tres propiedades en DbParameterCollection son abstractas en ensamblados de referencia pero virtuales de lo contrario?


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 multi-targeting, pero para los propósitos de esta pregunta solo necesitamos preocuparnos por net45.

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

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

Aquí está el código de ejemplo para reproducir el problema:

Archivo del 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 lo hace implementar DbParameterCollection del miembro abstracto heredado.Está sincronizado.get ' [c:\Users\skeet\Test\ParameterCollection\ParameterCollection.csproj]
Colección de maniquíes.cs (5,14): error CS0534: 'DummyParameterCollection' no implementa el miembro abstracto heredado 'DbParameterCollection.Tamaño fijado.get ' [c:\Users\skeet\Test\ParameterCollection\ParameterCollection.csproj]
Colección de maniquíes.cs (5,14): error CS0534: 'DummyParameterCollection' no implementa heredado abstract member 'DbParameterCollection.IsReadOnly.get ' [c:\Users\skeet\Test\ParameterCollection\ParameterCollection.csproj]

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

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

Puedo solucionar esto anulando las propiedades y simplemente devolviendo 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 que las asambleas de referencia no coinciden con las asambleas reales (y la documentación) en este caso? Esperaría que los ensamblajes de referencia se generen automáticamente, por lo que es extraño que algunas cosas sean incorrectas como esta...

Author: poke, 2017-05-26

1 answers

Las asambleas de referencia son correctas. 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 has adivinado, la diferencia entre los dos Sistemas.Datos.los ensamblados dll que está observando se deben a cómo. NET Framework separa los ensamblados de referencia y los ensamblados 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 el 4.5 versión 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á que el 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 actualiza in situ. 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 con la versión actualizada (con propiedades virtual, no abstract.)

En cuanto a soluciones: compilar para net451 en su lugar, o implementar métodos ficticios son los mejores enfoque. Usted podría hacer otros trucos para compilar contra una versión diferente del Sistema.Datos.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é 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 .

Se realizaron los siguientes cambios (sin interrupción) a la Sistema.API de datos en la versión 4.5.1 de. NET Framework....

Se añadió el siguiente miembro.

  • Sistema.Datos.Común.DbParameter.Precisión
  • Sistema.Datos.Común.DbParameter.Escala
  • Sistema.Datos.SqlClient.SqlConnectionStringBuilder.ConnectRetryCount
  • Sistema.Datos.SqlClient.SqlConnectionStringBuilder.ConnectRetryInterval

El siguiente miembro fue cambiado de abstracto a virtual.

  • Sistema.Datos.Común.DbDataReader.Cerrar
  • Sistema.Datos.Común.DbDataReader.GetSchemaTable
  • Sistema.Datos.Común.DbParameter.SourceVersion
  • Sistema.Datos.Común.DbParameterCollection.IsFixedSize
  • Sistema.Datos.Común.DbParameterCollection.IsReadOnly
  • Sistema.Datos.Común.DbParameterCollection.IsSynchronized
 16
Author: natemcmaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-10 06:40:32