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


68

我正在将项目从project.json转换为新的csproj格式,并且其中包括一个从派生的类DbParameterCollection。在我的实际项目中,我正在使用多目标,但是出于这个问题的目的,我们只需要关心即可net45

编译器告诉我,我必须重写以前不需要的三个属性:

如果遵循这些文档链接(适用于.NET 4.5),则会看到所有属性都是虚拟的-不是抽象的。如果我仅通过调用来构建代码csc,那么一切都很好……只有在使用.NET Core 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.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从所有属性中返回来解决此问题,但这是处理这种情况的最佳方法吗?除此之外,在这种情况下,参考程序集与实际程序集(和文档)不匹配有什么充分的理由吗?我希望参考程序集会自动生成,因此有些事情像这样不正确是很奇怪的...


虽然我没有Reflector,但我使用IL Disassembler来查看.NetFramework文件夹中的其他dll。v4.5之前的所有版本都具有这些属性,abstract而v4.5.1以后的版本都具有虚拟属性。至于为什么它们不同?我不能不说就说。
恩科西(Nkosi)

因此,我的猜测是virtual在参考程序集中v4.5之后,它们已被更改为增量更新,这也将解释为什么它会出现在Windows文件夹中最新版本的框架中。我参考(无双关语)这个问题stackoverflow.com/questions/9701135/…–
Nkosi

.net framework <= 3.5的API文档也显示了它abstract。在.net标准中,它也是抽象的。然而,在组装为CoreFx的System.Data.Common现在参照也显示它作为虚拟github.com/dotnet/corefx/blame/master/src/System.Data.Common/...
马丁乌尔里希

1
@SimonMourier:当然,我没有遇到任何问题-这只是事实,当文档声称这些属性看上去很抽象时,它们声称这些属性是虚拟的,而当我们使用它时,它又可以工作了project.json,这很奇怪……
Jon Skeet

8
@Somar:请停止建议使错误消息不可读的编辑(在很宽的一行上)。它是完全可读的。
乔恩·斯基特

Answers:


23

参考部件正确。在.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更改的官方文档,也找不到有关更改原因的解释,但是,我从Entity Framework团队的一个成员(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

以下成员从抽象更改为虚拟。

  • 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

5
感谢您的确认。我仍然不确定为什么要使用它来构建project.json,但这是另一个故事:)
Jon Skeet
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.