False CA1812 warning : "internal class that is apparently never instantiated..."
Asked Answered
S

4

17

I am getting a code analysis warning that seems to be a false-positive.

CA1812 : Microsoft.Performance : 'MyClass.MyPrivateClass' is an internal class that is apparently never instantiated. If so, remove the code from the assembly. If this class is intended to contain only static methods, consider adding a private constructor to prevent the compiler from generating a default constructor.

How do I get rid of this warning? I prefer to not suppress warnings unless I am sure I couldn't avoid it otherwise.

The classes look like this:

namespace Some.Namespace
{
    public class MyClass
    {
        private class MyPrivateClass
        {
            public int Id { get; set; }
            public ModelObject { get; set; }
        }
    }
}

I use it like this:

private IQueryable<MyPrivateClass> GetMyPrivateClasses()
{
    return this.Repository().All()
        .Select(m => new MyPrivateClass { Id = m.Id, ModelObject = m };
}

Does this usage not count as instantiation?

Spiccato answered 14/8, 2013 at 8:28 Comment(5)
Is GetMyPrivateClasses() itself definitely called? (Doesn't count if it is only called indirectly from another private method that's never called itself)Possess
@MatthewWatson Yes definitely. My code is all working correctly, and this particular method is a core part of my report, so yes.Spiccato
Even if it is called it is not clear if the class will be instantiated since this method returns a query without executing it (e.g. by using ToList).Eunuchoidism
It will be instantiated if the results of the query are materialized and if there is at least one result -- but since there's a repository in between you can't prove it statically. So you should probably suppress the warning and add a note explaining why to your future self. Alternatively you could perhaps replace your custom class with a Tuple, although this cure is IMHO worse than the disease.Deficiency
Use [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Late bound")]. Had same issue with reflection.Druid
C
22

I guess it is examining the IL; and genuinely - that IL does not ever contain a new MyPrivateClass instruction - because that statement is presumably running against IQueryable<T>, hence that lambda is an expression tree. It will contain some Expression.New, and some typeof(MyPrivateClass) - but no new MyPrivateClass.

In this case, the error is misleading. Simply suppress it.

Chickadee answered 14/8, 2013 at 8:37 Comment(5)
It's even said in the warning description explicitly: msdn.microsoft.com/en-us/library/ms182265.aspxEntablature
What is the syntax for suppressing this warning?Austen
I got this to work but had to restart VS2019 before the warning went away. #pragma warning disable CA1812 // Class is used for JSON deserialization .... #pragma warning restore CA1812Austen
After suppressing the warning, the project has to be built (or VS restarted, as @ThorkilVærge points out) for the warning to go away.Abvolt
This warning can also be suppressed using the an attribute. For example: [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Class is instantiated via dependency injection")] . Like others have mentioned, it appears that VS needs to be restarted for the suppression to take effect. Rebuilding was not enough to make the warning go away.Veasey
S
1

FYI there is a new documentation page for this warning:

https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1812

Instantiation of classes is not always recognized by analyzers.

Suppress this warning, if justified:

[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "generic/late bound/reflection")]

Happens especially in Net.Core.

Shep answered 26/10, 2022 at 19:49 Comment(0)
O
0

The only thing that worked for me was adding propertygroup and nowarn to the project in question:

  <PropertyGroup>
    <NoWarn>CA1812</NoWarn>
  </PropertyGroup>
Octan answered 24/11, 2023 at 15:51 Comment(0)
M
-1

Change your class to internal or public, that solves the problem. Anyway, you can extract your inner class from the outer class...

Monzonite answered 28/2, 2018 at 11:57 Comment(1)
This obviously changes intended private visibility of the class - it's not a solution if the class is to remain private or internal.Abvolt

© 2022 - 2024 — McMap. All rights reserved.