Use Nameof
ID |
csharp.use_nameof |
Severity |
high |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Code Smell |
Language |
CSharp |
Tags |
code_smell, exception, maintainability, refactoring |
Description
Reports a string literal inside a throw that writes out the name of a parameter in scope — either as
the whole literal, or spelled out inside a message — where nameof(parameter) should be used instead.
Rationale
A parameter name spelled out as text is invisible to the compiler and to every rename tool. Once someone renames the parameter, the literal keeps the old spelling: the exception then blames a parameter that no longer exists, and the developer reading the stack trace looks for something that is not in the signature.
nameof(parameter) produces the same string at compile time while staying attached to the
declaration, so a rename updates it and a typo becomes a compile error rather than a misleading
message at run time.
A message that spells the parameter out reads just as wrongly after a rename as the argument-name
position does, so it is reported too. That case needs a guard against accidental matches: a short name
turns up inside ordinary words — id inside identifier, path inside pathway — so a name that is
only contained in the literal is reported from five characters upwards. A whole-literal match is
reported at any length. The check stays limited to literals inside a throw.
Interpolated messages such as $"{documentPath} is unreadable" are already rename-safe and are not
reported.
using System;
public class Range
{
public void Check(int count, string id)
{
if (id == null)
{
throw new ArgumentNullException("id"); // FLAW — a rename leaves this behind
}
if (count < 0)
{
throw new ArgumentException("must be positive", "count"); // FLAW — same for the argument name
}
}
public void Open(string documentPath, string path)
{
if (documentPath == null)
{
throw new ArgumentException("documentPath must be provided"); // FLAW — the message names it
}
if (path == null)
{
throw new ArgumentException("the pathway is unknown"); // OK, under five characters
}
}
public void CheckOk(string id)
{
if (id == null)
{
throw new ArgumentNullException(nameof(id)); // OK, follows the rename
}
}
}
Remediation
Replace the literal with nameof(parameter). Where the parameter is named inside a message, keep the
prose and interpolate the name, as in $"{nameof(count)} must be positive", so the sentence follows a
rename as well as the argument-name position does.