Parameter name passed as a string literal instead of NameOf
ID |
vbnet.maintainability.use_nameof |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Api Design |
Language |
VB.NET |
Description
Reports argument-validation exceptions - ArgumentNullException, ArgumentException and
ArgumentOutOfRangeException - constructed with a hard-coded string literal in the
paramName position, where the NameOf operator should be used instead.
Rationale
A string literal parameter name is not checked by the compiler and is not updated by a
rename. When the parameter is renamed - by hand or by a refactoring tool - the literal keeps
the old name, so the exception blames a parameter that no longer exists and the message
reaching the caller, the log and the bug report is wrong. A typo in the literal has the same
effect and is never reported. NameOf is resolved at compile time, so a stale or misspelled
name becomes a compilation error rather than a misleading run-time message, and it costs
nothing at run time because the compiler emits the same constant string.
The following code illustrates the pattern detected by this rule:
Public Sub Register(ByVal userName As String, ByVal age As Integer)
' FLAGGED: Parameter name passed as a string literal instead of NameOf
If userName Is Nothing Then Throw New ArgumentNullException("userName")
' FLAGGED: Parameter name passed as a string literal instead of NameOf
If age < 0 Then Throw New ArgumentOutOfRangeException("age", "Age cannot be negative.")
End Sub
Remediation
Replace the literal with NameOf(parameter). Note the argument order differs between the
exception types: ArgumentNullException and ArgumentOutOfRangeException take paramName
first, while ArgumentException takes the message first and paramName second.
' Before: the literal survives a rename of the parameter
If userName Is Nothing Then Throw New ArgumentNullException("userName")
If age < 0 Then Throw New ArgumentOutOfRangeException("age", "Age cannot be negative.")
' After: the compiler keeps the name in step
If userName Is Nothing Then Throw New ArgumentNullException(NameOf(userName))
If age < 0 Then Throw New ArgumentOutOfRangeException(NameOf(age), "Age cannot be negative.")