访问类库中的mustoverride属性时出现AccessViolationException [英] AccessViolationException when accessing a mustoverride property in a class library
问题描述
这有点复杂,但是我会尽力解释清楚。
This is a little complex, but I'll try and explain clearly.
我有一个用于通用代码组件的类库;我尝试制作一些常见的 ConfigurationHandler
基类,以简化创建自定义配置节,集合和元素的过程。
I have a class library for common code components; and I tried to make some common ConfigurationHandler
base classes, to simplify creating custom configuration sections, collections and elements.
我最后得到的是:
ConfigurationSectionBase
类是通用的,采用 TConfElementCollection作为{ConfigurationElementCollection,New}
作为类型约束。
The ConfigurationSectionBase
class is generic, taking TConfElementCollection As {ConfigurationElementCollection, New}
as a type constraint.
此 ConfigurationSectionBase
类包含一个公共MustOverride属性集合,如TConfElementCollection
。
这个想法是,在使用类库的项目中,它们只需覆盖该集合并使用< ConfigurationProperty( CollectionName)>
属性对其进行修饰,例如:
The idea is that in the project using the class library, they simply have to override the collection and decorate it with the <ConfigurationProperty("CollectionName")>
attribute, e.g:
<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
效果很好-在使用的应用程序中,我可以创建该部分,然后在我的配置处理程序类中,可以调用
This was working fine - in the using application I could create the section, then in my config handler class I could call
Dim section As DerivedSection = (TryCast(Config.GetSection("DerivedSection"), DerivedSection))
Dim coll as DerivedConfigurationElementCollection = section?.Collection
那么,我的下一个想法是为什么不还抽象Config Handler类,并将其移入基类呢?
My next thought, then, was why not abstract the Config Handler class also, and move that into a base class?
这证明更复杂,但是我最终在DLL的 ConfigurationHandlerBase
类中获得了以下代码:
This proved more complex, but I ended up with the following code in a ConfigurationHandlerBase
class in the DLL:
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( ConfigurationSectionBase $中的
MustOverride
DLL中的c $ c>类,在使用的应用程序中覆盖了该类),然后尝试从类库中访问它-再次出现相同的问题。
To try and diagnose the problem, I made a String property in the same manner as the Collection (MustOverride
in the ConfigurationSectionBase
class in the DLL , overridden in the using application), then tried accessing that from the class library - and again, the same issue.
所以我认为问题与 MustOverride
有关,并且DLL代码无法识别出Derived类已覆盖属性。
So I think the issue is something to do with MustOverride
and the DLL code not recognising that the Derived class has overridden the Property.
如果我改为从DLL方法返回 TSection
,则在t中访问 Collection
属性使用DLL的应用程序;我可以很好地访问Collection。
If I return the TSection
from the DLL method instead, then access the Collection
property in the application that uses the DLL; I can access the Collection fine.
奇怪的是,如果我设置了断点,Visual Studio会很高兴地向我展示 Collection
属性,而不会引发任何异常。
The weird thing is, If I put a breakpoint in, Visual Studio will quite happily show me the contents of the Collection
property, without throwing any Exceptions.
此外,如果我替换(TryCast(Config.GetSection(sectionName ),TSection))
和 new TSection()
,我仍然收到AccessViolationException-因此,与我正在访问的事实无关据我所知,配置文件。
Also, if I replace (TryCast(Config.GetSection(sectionName), TSection))
with new TSection()
, I still get an AccessViolationException - so it's nothing to do with the fact that I'm accessing the Config File, as far as I can see.
以前有没有人遇到过这种情况?还是我下一步应该采取什么措施来解决此异常?
Has anyone come across this before; or what could my next steps be for troubleshooting this Exception?
推荐答案
您是vb.net编译器代码生成错误的受害者。 ,它会处理ConfigurationHandlerBase.GetCollection()方法的代码。使用约束调用会不适当地优化Collection属性的属性getter调用。看到它的最简单方法是在TestCollection.dll程序集上运行PEVerify.exe,尽管错误消息对我而言具有误导性:
You are a victim of a vb.net compiler code generation bug, it mangles the code for the ConfigurationHandlerBase.GetCollection() method. It inappropriately optimizes the property getter call for the Collection property, using a constrained call. Easiest way to see it is to run PEVerify.exe on the TestCollection.dll assembly, albeit that the error message looks misleading to me:
[IL]:错误:[C:\\ temp \\ temp \\ TestClassLibrary \\ TestClassLibrary \\ bin \\ Debug \\ testclasslibrary.dll:TestClassLibrary.ConfigurationHandlerBase`1 [TDerivedConfigHandler] :: GetCollection [TCollection,TSection]] [offset 0x00000024]
a约束调用的'this'参数必须具有ByRef类型。
1个错误,正在验证testclasslibrary.dll
[IL]: Error: [C:\temp\temp\TestClassLibrary\TestClassLibrary\bin\Debug\testclasslibrary.dll : TestClassLibrary.ConfigurationHandlerBase`1[TDerivedConfigHandler]::GetCollection[TCollection,TSection]][offset 0x00000024] The 'this' argument to a constrained call must have ByRef type. 1 Error(s) Verifying testclasslibrary.dll
正在搜索错误消息,但是使您落在此github.com问题。标记为固定的3个月前,我认为它是这个问题将其修复。此类修复程序在我们的计算机上运行时,并不总是很明显。不是今天。
Searching for the error message however lands you on this github.com issue. Marked as fixed 3 months ago, I think it was this SO question that got it repaired. It isn't always obvious when such fixes make it to our machines. Not today.
在github问题中提出的解决方法似乎无效。我看到的最简单的解决方法是避免使用elvis运算符,并重新使用基础知识,然后重写:
The workaround proposed in the github issue does not appear to be effective. Simplest workaround I see is to avoid the elvis operator and get back to basics, rewrite:
Dim coll As TCollection = s?.Collection
Return coll
收件人:
If s Is Nothing Then return Nothing Else Return s.Collection
这篇关于访问类库中的mustoverride属性时出现AccessViolationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!