Vb.net 访问类库中的mustoverride属性时发生AccessViolationException
这有点复杂,但我会尽量解释清楚 我有一个通用代码组件类库;我还尝试创建一些常见的Vb.net 访问类库中的mustoverride属性时发生AccessViolationException,vb.net,inheritance,dll,access-violation,Vb.net,Inheritance,Dll,Access Violation,这有点复杂,但我会尽量解释清楚 我有一个通用代码组件类库;我还尝试创建一些常见的ConfigurationHandler基类,以简化创建自定义配置节、集合和元素的过程 我最后得到的是: ConfigurationSectionBase类是泛型的,将tconfementCollection作为{ConfigurationElementCollection,New}作为类型约束 此ConfigurationSectionBase类包含一个Public MustOverride属性集合作为tconfe
ConfigurationHandler
基类,以简化创建自定义配置节、集合和元素的过程
我最后得到的是:
ConfigurationSectionBase
类是泛型的,将tconfementCollection作为{ConfigurationElementCollection,New}
作为类型约束
此ConfigurationSectionBase
类包含一个Public MustOverride属性集合作为tconfementCollection
其思想是,在使用类库的项目中,他们只需覆盖集合并使用
属性对其进行修饰,例如:
<ConfigurationProperty("CollectionName")>
Public Overrides Property Collection As DerivedConfigurationElementCollection
Get
Return TryCast(Me("CollectionName"), DerivedConfigurationElementCollection)
End Get
Set(value As DerivedConfigurationElementCollection)
Me("CollectionName") = value
End Set
End Property
那么,我的下一个想法是,为什么不将配置处理程序类也抽象出来,并将其移动到基类中呢
这证明更复杂,但我在DLL中的ConfigurationHandlerBase
类中得到了以下代码:
Protected Function GetCollection(Of TCollection As ConfigurationElementCollection, TSection As {ConfigurationSectionBase(Of TCollection), New})(sectionName as String) As TCollection
Dim s As TSection = (TryCast(Config.GetSection(sectionName), TSection))
Return s?.Collection ' AccessViolationException is thrown on this line
为了尝试诊断这个问题,我以与集合相同的方式创建了一个字符串属性(MustOverride
在DLL中的ConfigurationSectionBase
类中,在使用应用程序中被重写),然后尝试从类库访问该属性,同样的问题再次出现
因此,我认为问题与MustOverride
有关,并且DLL代码没有识别出派生类已经重写了属性
如果我从DLL方法返回t部分
,则访问使用DLL的应用程序中的集合
属性;我可以很好地访问收藏
奇怪的是,如果我在中放置断点,VisualStudio将非常高兴地向我显示集合
属性的内容,而不会抛出任何异常
另外,如果我将(TryCast(Config.GetSection(sectionName),TSection))
替换为new TSection()
,我仍然会得到一个AccessViolationException,所以就我所见,这与我访问配置文件的事实无关
以前有没有人遇到过这个问题;或者我的下一步是如何排除此异常的?您是vb.net编译器代码生成错误的受害者,它会损坏ConfigurationHandlerBase.GetCollection()方法的代码。它使用受约束的调用不适当地优化了集合属性的属性getter调用。查看它的最简单方法是在TestCollection.dll程序集上运行PEVerify.exe,尽管错误消息在我看来有误导性: [IL]:错误:[C:\temp\temp\TestClassLibrary\TestClassLibrary\bin\Debug\TestClassLibrary.dll:TestClassLibrary.ConfigurationHandlerBase`1[TDerivedConfigHandler]::GetCollection[TCollection,TSection][offset 0x00000024]将“this”参数设置为 受约束调用必须具有ByRef类型。 验证testclasslibrary.dll时出现1个错误 但是,搜索错误消息会使您陷入困境。3个月前标记为已修复,我想是它修复的。当这样的修正应用到我们的机器上时,它并不总是显而易见的。今天不行 github问题中提出的解决方案似乎并不有效。我所看到的最简单的解决方法是避免使用elvis运算符,回到基础,重写:
Dim coll As TCollection = s?.Collection
Return coll
致:
@HansPassant see看起来像是带有泛型的null条件运算符上的编译器或抖动错误(还没有仔细研究哪一个)。将
Dim coll替换为TCollection=s?.Collection
,将Dim coll替换为TCollection=IIf(s为Nothing,Nothing,s.Collection)
,问题消失。当然,如果编译器工作正常,这些语句应该是等价的。
Dim coll As TCollection = s?.Collection
Return coll
If s Is Nothing Then return Nothing Else Return s.Collection