I have the code similar to the following in one of my projects:
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;
}
When I run FxCop on this code, I get run into warning CA1049. This struct is used for interoperability with a native code library, so it pretty much has to have this layout. Why does FxCop give me grief about this struct? I have other structs in the same source file, which also have IntPtr
members, but FxCop does not complain about those.
For example, the following code does not trigger the same warning:
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;
}
I suppose I could implement IDisposable
on the struct, but that just seems wrong. Likewise, I could simply suppress the warning, but at the moment, I want to understand what it is about this particular struct that is triggering the warning, when it's not that much different than the other seven structs I have in the same source file. Alternatively, I'd happily accept an explanation of why the other structs don't trigger this warning.
The Code Anylsis engine produces this warning any time you have a managed type that includes a member of what it considers a "native" type. To be a native type, the field must:
IntPtr
, UIntPtr
, or a HandleRef
static
I'm pretty sure that this third bullet is probably the difference between your various structures. The analysis engine (based on a quick dotPeek perusal) will only trigger the warning if it actually finds an instance of your IntPtr
being assigned from native code. I haven't yet found exactly what it considers an "assignment from native code" but whatever that is, my best guess is only one of you various struct
types is triggering that part of the rule.
Note that this is based on reading the actual code of the current implementation of the Code Analysis engine as ships with VS2010. It is absolutely not a documented behavior of the rule, but likely a specific optimization to reduce false positives. You should not assume that code which currently "passes" this rule (e.g. because it's never assigned from native code) will always do so, as MS is free to change the implementation details at any time.
As mentioned in my comment, suppressing the message is a perfectly legitimate response in this case; this is not one of the FxCop rules that should never be suppressed. The rule is very context-specific and only applies if you're allocating a native resource of your own. If you are only passing the struct back and forth between C# and unmanaged code, then you can most likely just suppress the warning and move on.
It's quite clearly spelled out in the article you linked:
This rule assumes that IntPtr, UIntPtr, and HandleRef fields store pointers to unmanaged resources. Types that allocate unmanaged resources should implement IDisposable to let callers to release those resources on demand and shorten the lifetimes of the objects that hold the resources.
So just the plain appearance of IntPtr in the struct is enough to trigger the warning. After you verified that you really didn't forget to release the native resource, apply the [SuppressMessage] attribute on the struct to not have to look at this message again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With