Почему три свойства в DbParameterCollection абстрактные в ссылочных сборках, но виртуальные в противном случае?
я перемещаю проект из project.json
в новый формат csproj, и он включает класс, производный от DbParameterCollection
. В моем реальном проекте я использую мульти-таргетинг, но для целей этого вопроса нам нужно только заботиться о net45
.
компилятор говорит мне, что я должен переопределить три свойства, которые мне не пришлось раньше:
если вы перейдете по этим ссылкам документации (которые предназначены для .NET 4.5), вы увидите, что все свойства виртуальный - не абстрактный. Если я создам код, просто позвонив csc
, все хорошо... это только при использовании .Чистый базовый пакет SDK, что я бегу в проблему.
вот пример кода для воспроизвести проблему:
файл проекта:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net45</TargetFramework>
</PropertyGroup>
</Project>
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;
}
ошибки:
DummyParameterCollection.cs (5,14): ошибка CS0534: 'DummyParameterCollection' не реализует унаследованный абстрактный член 'DbParameterCollection.IsSynchronized.сделать' [c:UsersskeetTestParameterCollectionParameterCollection.csproj]
DummyParameterCollection.cs(5,14): ошибка CS0534: 'DummyParameterCollection' не делает реализовать унаследованный абстрактный элемент ' DbParameterCollection.IsFixedSize.сделать' [c:UsersskeetTestParameterCollectionParameterCollection.csproj]
DummyParameterCollection.cs (5,14): ошибка CS0534: 'DummyParameterCollection' не реализует унаследованный абстрактный член 'DbParameterCollection.IsReadOnly.сделать' [c:UsersskeetTestParameterCollectionParameterCollection.csproj]
я считаю, что знаю непосредственную причину проблемы, но не причины почему это как это, или лучшим решением.
похоже, что .NET Core SDK (и VS2017 при загрузке этого проекта) использует ссылочные сборки. Если я открою C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.5System.Data.dll
в рефлектор, это показывает свойства как абстрактные, а также. Тогда как если я открою c:WindowsMicrosoft.NETFrameworkv4.0.30319System.Data.dll
, что показывает свойства, как виртуальную.
я могу обойти это, переопределив свойства и просто вернув false
от всех них - но разве это лучший способ справиться с этой ситуацией? Кроме того, есть ли веская причина, по которой ссылочные сборки не соответствуют реальным сборкам (и документации) в этом случае? Я ожидал бы, что ссылочные сборки будут автоматически генерироваться, поэтому это странно для некоторые вещи, чтобы быть неправильным, как это...
1 ответ:
ссылочные сборки верны. В .NET Framework 4.5 эти свойства были
abstract
. Они были изменены наvirtual
в .NET Framework 4.5.1. Похоже, вы обнаружили ошибку в документации.как вы, наверное, уже догадались, разница между двумя системами.Данные.сборки dll, которые вы наблюдаете, связаны с тем, как .NET Framework разделяет ссылочные сборки и сборки среды выполнения. Ссылочная сборка в
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll
точно отражает то, что бы был в версии 4.5 времени выполненияSystem.Data.dll
. Если вы можете получить старую машину, которая еще не обновлена до .NET Framework 4.5.1 (good luck), вы найдете эту сборку времени выполнения вC:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll
имеет эти свойства какabstract
. Обновление .NET Framework на месте. На компьютере, обновленном до .NET Framework 4.5.1 или более поздней версии,C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll
была заменена на обновленную версию (сvirtual
, а неabstract
свойства.)что касается обходных путей: компиляция для
net451
вместо этого, или внедрение фиктивных методов является лучшим подходом. Вы можете сделать другие трюки для компиляции против другой версии системы.Данные.dll, но я бы не рекомендовал егоЯ не смог найти официальную документацию по изменениям API между .NET Framework 4.5 и 4.5.1 или объяснение того, почему это было изменено, однако я нашел этот комментарий от члена команды Entity Framework:https://bugzilla.xamarin.com/show_bug.cgi?id=29167#c0.
в систему были внесены следующие (неразрушающие) изменения.API данных в выпуске .NET Framework 4.5.1....
были добавлены следующие элементы.