Parameter Shadows Property
ID |
csharp.parameter_shadows_property |
Severity |
low |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
CSharp |
Tags |
naming, reliability |
Description
Reports a method or constructor parameter whose name matches a property declared on
the enclosing class. The parameter shadows the property in the body: any unqualified
use of the name resolves to the parameter, and the property must be reached through
this.X. Forgetting the qualifier silently reads or assigns the parameter when the
property was meant.
Rationale
C# name resolution gives the local parameter priority over the enclosing-class
property. The compiler does not warn, so a missing this. is invisible to the
reader and produces wrong results at runtime — typically a property that "doesn’t
update" or a constructor parameter that "doesn’t take effect".
public class Order
{
public int Total { get; set; }
public void Add(int Total) // FLAW — Total shadows the property
{
Total = Total + 1; // assigns the parameter, not the property
}
public void AddOk(int amount) // OK — distinct name
{
Total = Total + amount;
}
public Order(int Total) // OK — this.Total = Total is the canonical assign-from-param idiom
{
this.Total = Total;
}
}
A constructor parameter is exempt when the constructor’s body assigns it straight to the
same-named property (this.Total = Total;) — the shadow is resolved deliberately and
correctly at that one line, so there is nothing to rename. The exemption is scoped to
constructors: Add(int Total) above would keep being flagged even if it were rewritten as
this.Total = Total;, because an ordinary method mixing a parameter with reads of the same
property elsewhere is not the same shape as a constructor’s one-line initialisation.
Remediation
Rename the parameter so it cannot be confused with the property — the conventional
camelCase parameter / PascalCase property split removes the collision and the
need for a this. qualifier.