Search code examples
c#winapipinvokecompiler-warnings

Do not declare visible instance fields warning in sequential struct


I'm using some DllImports in a wpf application to capture the screen. I'm calling GetWindowRect in user32.dll. It requires a rect struct passed to it. The layout of the struct matters, since it's a native call.

I'm trying out VS 2019 preview 2 which gives me warnings I hadn't seen before. All the fields in rect generate the same warning:

CA1051 Do not declare visible instance fields

In the rest of the code, I fixed this by turning the field into a property by appending {get;set;} to it. I don't know if I can safely do this in a struct where layout matters.

Rect is also giving me a warning that I should override Equals.

CA1815 Rect should override Equals.

CA1815 Rect should override the equality (==) and inequality (!=) operators.

I never compare it though and definitely don't need to, I just want to fix the warning.

public static class NativeMethods
{
    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();

    public static IntPtr _GetForegroundWindow()
    {
        return GetForegroundWindow();
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
    private static extern IntPtr GetDesktopWindow();

    public static IntPtr _GetDesktopWindow()
    {
        return GetDesktopWindow();
    }

    //Am unable to get code analysis to shut up about this.
    [DllImport("user32.dll")]
    private static extern int GetWindowRect(IntPtr hWnd, ref Rect rect);

    public static IntPtr _GetWindowRect(IntPtr hWnd, ref Rect rect)
    {
        return (IntPtr)GetWindowRect(hWnd, ref rect);
    }        
}

[StructLayout(LayoutKind.Sequential)]
public struct Rect
{
    public int Left;
    public int Top;
    public int Right;
    public int Bottom;
}    

How can I fix these warnings?


Solution

  • The documentation of CA1051: Do not declare visible instance fields says:

    Cause

    An externally visible type has an externally visible instance field.

    The key point for both type and field is external. Hence the fix (since this is supposed to be used only inside your application) is to make the struct (and the class that exposes it) internal:

    [StructLayout(LayoutKind.Sequential)]
    internal struct Rect
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }    
    
    internal static class NativeMethods
    {
        // ...
    }
    

    Please note that CA1051 warning is not generated by the C# compiler, but Code Analysis, hence can be excluded or ignored from the CA rule set (although the documentation suggests to not suppress it).