我的一个项目中的代码类似于以下代码:
internal enum ArtworkType
{
Undefined = 0,
Bmp = 1,
Gif = 2,
Jpeg = 3,
Png = 4
}
[StructLayout(LayoutKind.Sequential)]
internal struct TagArtwork
{
internal IntPtr data;
internal int size;
internal ArtworkType type;
}
当我在这段代码上运行FxCop时,我会遇到警告CA1049。此结构用于与本机代码库的互操作性,因此几乎 具有此布局。为什么FxCop让我对这个结构感到悲伤?我在同一个源文件中有其他结构,也有IntPtr
个成员,但FxCop并不抱怨这些结构。
例如,以下代码不会触发相同的警告:
internal enum ItemType
{
Implicit = 0,
Utf8 = 1,
Utf16 = 2,
Sjis = 3,
Html = 6,
Xml = 7,
Uuid = 8,
Isrc = 9,
Mi3p = 10,
Gif = 12,
Jpeg = 13,
Png = 14,
Url = 15,
Duration = 16,
DateTime = 17,
Genres = 18,
Integer = 21,
Riaa_pa = 24,
Upc = 25,
Bmp = 27,
Undefined = 255
}
[StructLayout(LayoutKind.Sequential)]
internal struct MP4ItmfData
{
internal byte typeSetIdentifier;
internal ItemType typeCode;
internal int locale;
internal IntPtr value;
internal int valueSize;
}
我想我可以在结构上实现IDisposable
,但这似乎是错误的。同样,我可以简单地抑制警告,但此时,我想了解触发警告的这个特定结构是什么,当它与我在同一源文件中的其他七个结构没有那么大的不同。或者,我很乐意接受一个解释为什么其他结构不会触发此警告。
答案 0 :(得分:7)
Code Anylsis引擎会在您拥有包含其认为是“本机”类型的成员的托管类型时生成此警告。要成为本机类型,该字段必须:
IntPtr
,UIntPtr
或HandleRef
static
我很确定这第三个子弹可能是你的各种结构之间的差异。分析引擎(基于快速dotPeek perusal)仅在实际发现从本机代码分配IntPtr
的实例时才会触发警告。我还没有找到它认为“从本机代码中分配”的确切内容,但无论如何,我最好的猜测只是你们中的一个struct
类型触发了规则的这一部分。
请注意,这是基于VS2010随附的代码分析引擎的当前实现的实际代码。绝对不规则的记录行为,但可能是减少误报的特定优化。您不应该假设当前“通过”此规则的代码(例如,因为它从未从本机代码分配)将始终这样做,因为MS可以随时更改实现细节。
正如我在评论中所提到的,在这种情况下,压制消息是完全合法的回应;这不是永远不应该被压制的FxCop规则之一。该规则特定于上下文,仅在您分配您自己的本机资源时才适用。如果您只是在C#和非托管代码之间来回传递结构,那么您很可能只是禁止警告并继续前进。
答案 1 :(得分:2)
在您链接的文章中非常清楚地说明了这一点:
此规则假定IntPtr,UIntPtr和HandleRef字段存储指向非托管资源的指针。分配非托管资源的类型应实现IDisposable,以允许调用者按需释放这些资源,并缩短保存资源的对象的生命周期。
因此,结构中IntPtr的简单外观足以触发警告。在验证确实没有忘记释放本机资源后,在结构上应用[SuppressMessage]属性,不必再次查看此消息。