是否可以在C#中创建一个非盒式结构

时间:2014-07-13 08:22:44

标签: c# clr boxing chakra

某些数据的副本不属于堆(没有特殊处理。)例如,堆栈上的JavaScriptValue结构在与Chakra JavaScript引擎互操作方面做得很好。

但据我了解,在托管堆上存储这样的值(没有正确的引用计数)会导致可能的悬空引用。有没有办法将这样的c#结构声明为 non-boxable

澄清,如果在类型上生成任何装箱操作,我希望c#编译器生成错误消息。

参考:请参阅MSDN JSAddRef reference,其中包含:

  

这只需要在 不会存储的JsRef句柄上调用   在堆栈的某个地方。 调用JsAddRef可确保JsRef引用的对象>   在调用JsRelease之前不会被释放。

我从中收集到Chakra可能正在使用“保守的垃圾收集”方法,使得JsAddRef / JsRelease不需要基于堆栈的JsRef句柄。我想用来使用类(不是结构) )将JsRef句柄包装在堆上,并进行转换操作以调用JsAddRef,并使用IDisposable模式调用JsRelease。

4 个答案:

答案 0 :(得分:1)

对于 C# 7.2+,答案是肯定的:只需在结构 placefields = np.reshape(placefields,(len(placefields),99,1)) nspikes = np.swapaxes(np.tile(spikes, (xybins,1,1)),0,1) probability = np.empty((len(spikes[0]), xybins)) chunks = len(spikes[0])//20 n = int(len(spikes[0])/chunks) for i in range(0,len(nspikes[0][0]),n): nspikes_chunk = nspikes[:,:,i:i+n] probability_chunk = stats.poisson.pmf(nspikes_chunk,placefields) probability_chunk = np.swapaxes(probability_chunk.prod(axis=0),0,1) if len(probability_chunk)<(len(spikes)//chunks): probability[i:] = probability_chunk else: probability[i:i+len(probability_chunk)] = probability_chunk 上使用 ref 关键字。只允许在堆栈上,而不是在堆上(因此不能对其进行装箱)。

请参阅此处了解更多信息:http://www.devsanon.com/c/c-7-2-introducing-ref-struct/

这里: https://docs.microsoft.com/en-us/dotnet/csharp/write-safe-efficient-code#use-ref-struct-types

答案 1 :(得分:0)

它被装箱,因为你将它存储在堆上的数据结构中。

将它包装在非值类型中。

围绕这个主题有很多问题。如果你不想读一本书,那么你应该阅读所有这些。其中一些很有趣。

所以没有不可能创建一个非盒式结构 - 因为你做了什么,它会被装箱。

答案 2 :(得分:0)

CLI ECMA-335 specification说(第I.8.2.4节):

  

所有值类型都有一个名为box的操作。装箱任何值类型的值会产生其盒装值;即,包含该按位副本的相应盒装类型的值   原始价值。

还有一些额外的语言说明Nullable<T>会发生什么(包含的值被装箱或产生空引用),并且无法对托管指针执行框操作,但没有提及任何异常对于价值类型。

答案 3 :(得分:0)

正如其他人所写的那样,值类型将被装箱(您可以将其视为包含在引用类型中)以便能够进入堆中。

但更重要的是,这与悬挂引用和引用计数无关。无论存放在哪里都无关紧要。

我相信你所问的是如何管理原生资源,这是另一回事。如果从.NET世界之外的某些东西分配资源,通常需要确保在完成后释放/释放它。通常,您将其包装在一个实现IDisposable的类中,并手动(或在析构函数中)处理它。现在,如果你忘了处理你应该做的事情,或者保留对已经处置的东西的引用,你就会遇到麻烦。但这一切都取决于资源是什么。

对于JavaScriptValue的特定情况,我真的不知道它是如何工作的。虽然在我看来,如果那里的IntPtr引用了需要处理的东西,JavaScriptValue将是一个实现IDisposable而不是结构的类。存储需要在结构中处理的内容将是一种非常好的陷入困境的方法,因为您可能会在整个地方都有该引用的副本。所以我假设你不需要打扰 - 但你应该检查文档以确定。