为什么DbParameterCollection中的三个属性在引用程序集中是抽象的,否则是虚拟的?

Jon*_*eet 67 c# assemblies .net-core

我正在将一个项目从project.json一个新的csproj格式转移到它,它包含一个派生自的类DbParameterCollection.在我的真实项目中,我使用多目标,但出于这个问题的目的,我们只需要关心net45.

编译器告诉我,我必须覆盖以前没有的三个属性:

如果您按照这些文档链接(适用于.NET 4.5),您将看到所有属性都是虚拟的 - 而不是抽象的.如果我只是通过调用来构建代码csc,那么一切都很好......只有当我使用.NET Core SDK时才遇到问题.

以下是重现问题的示例代码:

项目文件:

<Project Sdk="Microsoft.NET.Sdk">    
  <PropertyGroup>
    <TargetFramework>net45</TargetFramework>
  </PropertyGroup>    
</Project>
Run Code Online (Sandbox Code Playgroud)

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;
}
Run Code Online (Sandbox Code Playgroud)

错误:

DummyParameterCollection.cs(5,14):错误CS0534:'DummyParameterCollection'没有实现继承的抽象成员'DbParameterCollection.IsSynchronized.get'[c:\ Users\skeet\Test\ParameterCollection\ParameterCollection.csproj]
DummyParameterCollection.cs(5, 14):错误CS0534:'DummyParameterCollection'没有实现继承的抽象成员'DbParameterCollection.IsFixedSize.get'[c:\ Users\skeet\Test\ParameterCollection\ParameterCollection.csproj]
DummyParameterCollection.cs(5,14):错误CS0534: 'DummyParameterCollection'不实现继承的抽象成员'DbParameterCollection.IsReadOnly.get'[c:\ Users\skeet\Test\ParameterCollection\ParameterCollection.csproj]

我相信我知道问题的直接原因,但不知道为什么会这样,或最好的解决方法.

它看起来像.NET Core SDK(和VS2017加载此项目时)使用引用程序集.如果我C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll在Reflector中打开,则表明属性也是抽象的.而如果我打开c:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll,则表明属性是虚拟的.

我可以通过覆盖属性并false从所有属性返回来解决这个问题- 但这是处理这种情况的最佳方法吗?除此之外,在这种情况下,参考组件与真实组件(和文档)不匹配是否有任何理由?我希望引用程序集是自动生成的,所以有些事情是不正确的,这是奇怪的......

nat*_*ter 22

参考组件是正确的.在.NET Framework 4.5中,这些属性是abstract.它们virtual在.NET Framework 4.5.1中已更改为.看来你已经发现了一个文档错误.

您可能已经猜到,您正在观察的两个System.Data.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的旧计算机(祝您好运),您会发现运行时程序集中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而不是实现虚拟方法是最好的方法.你可以做其他技巧来编译不同版本的System.Data.dll,但我不推荐它

我找不到关于.NET Framework 4.5和4.5.1之间的API更改的官方文档,或者解释为什么会更改它,但是,我从实体框架团队的成员那里找到了这条评论:https:// bugzilla. xamarin.com/show_bug.cgi?id=29167#c0.

对.NET Framework 4.5.1版本中的System.Data API进行了以下(非破坏性)更改....

添加了以下成员.

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

以下成员从abstract更改为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

  • 谢谢你的确认.我仍然不确定它为什么用`project.json`来构建,但这是另一个故事:) (5认同)