为什么引用程序集中的DbParameterCollection抽象中有三个属性,否则是虚拟的?
我将项目从project.json
移动到新样式的csproj格式,它包含从DbParameterCollection
派生的类。 在我真正的项目中,我正在使用多目标,但为了这个问题的目的,我们只需要关心net45
。
编译器告诉我,我必须重写以前没有的三个属性:
-
IsFixedSize
-
IsReadOnly
-
IsSynchronized
如果你遵循这些文档链接(这是用于.NET 4.5),你会看到所有的属性是虚拟的 – 而不是抽象的。 如果我只是通过调用csc
构build代码,一切都很好……只有在使用.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'没有实现inheritance的抽象成员'DbParameterCollection.IsSynchronized.get'[c:\ Users \ skeet \ Test \ ParameterCollection \ ParameterCollection.csproj]
DummyParameterCollection.cs(5,14):错误CS0534:'DummyParameterCollection'没有实现inheritance的抽象成员'DbParameterCollection.IsFixedSize.get'[c:\ Users \ skeet \ Test \ ParameterCollection \ ParameterCollection.csproj]
DummyParameterCollection.cs(5,14):错误CS0534:'DummyParameterCollection'没有实现inheritance的抽象成员'DbParameterCollection.IsReadOnly.get'[c:\ Users \ skeet \ Test \ ParameterCollection \ ParameterCollection.csproj]
我相信我知道问题的直接原因,但不是这个原因,或者最好的解决方法。
它看起来像.NET核心SDK(和VS2017当它加载这个项目)使用引用程序集。 如果我在Reflector中打开C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Data.dll
, 那么也显示属性是抽象的。 而如果我打开c:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Data.dll
,则显示属性为虚拟。
我可以通过覆盖这些属性来解决这个问题,只是从所有这些属性中返回false
,但这是处理这种情况的最好方法吗? 除此之外,在这种情况下,引用程序集与实际程序集(和文档)不匹配的原因是否有充分的理由? 我期望引用程序集是自动生成的,所以有些事情是不正确的,这是奇怪的…
参考assembly是正确的。 在.NET Framework 4.5中,这些属性是abstract
。 他们在.NET Framework 4.5.1中被更改为virtual
。 看来你已经发现了一个文档错误。
正如你可能已经猜到的那样,你所观察到的两个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
find该运行时assemblyC:\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
replace为更新后的版本(使用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