访问类库中的 mustoverride 属性时出现 AccessViolationException [英] AccessViolationException when accessing a mustoverride property in a class library

查看:20
本文介绍了访问类库中的 mustoverride 属性时出现 AccessViolationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这有点复杂,但我会尽量解释清楚.

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 As {ConfigurationElementCollection, New} 作为类型约束.

The ConfigurationSectionBase class is generic, taking TConfElementCollection As {ConfigurationElementCollection, New} as a type constraint.

这个 ConfigurationSectionBase 类包含一个 Public MustOverride 属性集合 As TConfElementCollection.

This ConfigurationSectionBase class contains a Public MustOverride Property Collection As 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 相同的方式创建了一个 String 属性(MustOverride 在 DLL 的 ConfigurationSectionBase 类中,在 using 中覆盖应用程序),然后尝试从类库访问它 - 再次出现同样的问题.

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 代码没有识别出派生类已经覆盖了属性有关.

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,则访问使用 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: emp empTestClassLibraryTestClassLibraryinDebug estclasslibrary.dll:TestClassLibrary.ConfigurationHandlerBase`1[TDerivedConfigHandler]::GetCollection[TCollection,TSection]][offset 0x00000024]'this' 的论点受约束的调用必须具有 ByRef 类型.1 Error(s) 验证 testclasslibrary.dll

[IL]: Error: [C: emp empTestClassLibraryTestClassLibraryinDebug estclasslibrary.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 个月前标记为固定,我认为是 this SO question 修复了它.当此类修复应用到我们的机器上时,并不总是很明显.不是今天.

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 issue 中提出的解决方法似乎没有效果.我看到的最简单的解决方法是避免使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆