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

查看:100
本文介绍了访问类库中的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作为{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屋!

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