Avoid Uninstantiated Internal

ID

csharp.avoid_uninstantiated_internal

Severity

low

Remediation Complexity

medium

Remediation Risk

low

Remediation Effort

medium

Resource

Code Smell

Language

CSharp

Tags

code_smell, dead_code

Description

Reports internal (non-public, non-protected, non-private) classes that are never instantiated anywhere in the scanned project. The analysis is project-wide: object creations from every file are combined, so an internal class declared in one file and constructed from another is correctly considered used. Classes a framework may activate out of band are excluded: static, abstract and partial classes, classes carrying attributes, entry-point holders (a static Main), and classes with a base list (DI containers, storyboards and test runners instantiate subclasses reflectively).

Rationale

If nothing creates an instance of an internal class, none of its instance code can ever run. The class is dead weight: it clutters the file, increases the surface that maintainers must read, and risks confusing reviewers about which code path is actually in use. Removing it is safe within the assembly.

internal class UnusedHelper                                          // FLAW
{
    public void DoWork() { }
}

internal class UsedHelper
{
    public void DoWork() { }
}

internal class Caller
{
    public void Run()
    {
        var helper = new UsedHelper();                               // OK reference
        helper.DoWork();
    }
}

public class PublicHelper { }                                        // OK - public surface, callers may live in other assemblies

[Serializable]
internal class ReflectionWired { }                                   // OK - attribute may wire it up reflectively

Remediation

Delete the class, or make it public if other assemblies actually need it. If the class is wired up reflectively (e.g. by JSON serialisation), add the relevant attribute so the rule can see the intent.