访问类库中的mustoverride属性时发生AccessViolationException
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了访问类库中的mustoverride属性时发生AccessViolationException相关的知识,希望对你有一定的参考价值。
这有点复杂,但我会尽力解释清楚。
我有一个用于公共代码组件的类库;我尝试制作一些常见的ConfigurationHandler
基类,以简化创建自定义配置节,集合和元素。
我最终得到的是:
ConfigurationSectionBase
类是通用的,将TConfElementCollection As {ConfigurationElementCollection, New}
作为类型约束。
这个ConfigurationSectionBase
类包含Public MustOverride Property Collection As TConfElementCollection
。
我们的想法是,在使用类库的项目中,他们只需要覆盖集合并使用<ConfigurationProperty("CollectionName")>
属性进行装饰,例如:
<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
这工作正常 - 在使用应用程序中我可以创建该部分,然后在我可以调用的配置处理程序类中
Dim section As DerivedSection = (TryCast(Config.GetSection("DerivedSection"), DerivedSection))
Dim coll as DerivedConfigurationElementCollection = section?.Collection
那么,我的下一个想法是,为什么不抽象Config Handler类,并将其移到基类中?
事实证明这更复杂,但我最终在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
为了尝试和诊断问题,我以与Collection相同的方式创建了一个String属性(DLL中的MustOverride
类中的ConfigurationSectionBase
,在使用的应用程序中被覆盖),然后尝试从类库中访问它 - 再次,同样问题。
所以我认为这个问题与MustOverride
和DLL代码无关,因为它没有认识到Derived类已经覆盖了Property。
如果我从DLL方法返回TSection
,则访问使用DLL的应用程序中的Collection
属性;我可以访问收藏品。
奇怪的是,如果我放入一个断点,Visual Studio将非常高兴地向我展示Collection
属性的内容,而不会抛出任何异常。
另外,如果我用(TryCast(Config.GetSection(sectionName), TSection))
替换new TSection()
,我仍然会得到一个AccessViolationException - 所以这与我访问配置文件的事实无关,据我所见。
有没有人遇到过这个问题;或者我的下一步可以解决此异常的问题?
您是vb.net编译器代码生成错误的受害者,它破坏了ConfigurationHandlerBase.GetCollection()方法的代码。它使用约束调用不恰当地优化了Collection属性的属性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类型。 1错误验证testclasslibrary.dll
然而,搜索错误消息会让你登陆this github.com issue。 3个月前标记为固定,我认为是this SO question修复它。当这些修复程序进入我们的机器时,并不总是很明显。今天不行。
github问题中提出的解决方法似乎没有效果。我看到的最简单的解决方法是避免使用elvis操作符并返回基础,重写:
Dim coll As TCollection = s?.Collection
Return coll
至:
If s Is Nothing Then return Nothing Else Return s.Collection
以上是关于访问类库中的mustoverride属性时发生AccessViolationException的主要内容,如果未能解决你的问题,请参考以下文章