80 lines
3.6 KiB
Plaintext
80 lines
3.6 KiB
Plaintext
== Why is this an issue?
|
|
|
|
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/caller-information[Caller information attributes] provide a way to get information about the caller of a method through https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments#optional-arguments[optional] parameters. But they only work right if their values aren't provided explicitly. So if you define a method with caller info attributes in the middle of the parameter list, the caller is forced to use named arguments if they want to use the method properly.
|
|
|
|
This rule raises an issue when the following attributes are used on parameters before the end of the parameter list:
|
|
|
|
* https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerfilepathattribute[CallerFilePathAttribute]
|
|
* https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerlinenumberattribute[CallerLineNumberAttribute]
|
|
* https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callermembernameattribute[CallerMemberNameAttribute]
|
|
* https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute[CallerArgumentExpressionAttribute]
|
|
|
|
== How to fix it
|
|
|
|
Move the decorated parameters to the end of the parameter list.
|
|
|
|
=== Code examples
|
|
|
|
==== Noncompliant code example
|
|
|
|
[source,csharp,diff-id=1,diff-type=noncompliant]
|
|
----
|
|
void TraceMessage([CallerMemberName] string memberName = "",
|
|
[CallerFilePath] string filePath = "",
|
|
[CallerLineNumber] int lineNumber = 0,
|
|
string message = null) // Noncompliant: decorated parameters appear before "message" parameter
|
|
{
|
|
/* ... */
|
|
}
|
|
----
|
|
|
|
==== Compliant solution
|
|
|
|
[source,csharp,diff-id=1,diff-type=compliant]
|
|
----
|
|
void TraceMessage(string message = null,
|
|
[CallerMemberName] string memberName = "",
|
|
[CallerFilePath] string filePath = "",
|
|
[CallerLineNumber] int lineNumber = 0)
|
|
{
|
|
/* ... */
|
|
}
|
|
----
|
|
|
|
== Resources
|
|
|
|
=== Documentation
|
|
|
|
* https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/caller-information[Determine caller information using attributes interpreted by the C# compiler]
|
|
* https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerfilepathattribute[CallerFilePathAttribute Class]
|
|
* https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerlinenumberattribute[CallerLineNumberAttribute Class]
|
|
* https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callermembernameattribute[CallerMemberNameAttribute Class]
|
|
* https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute[CallerArgumentExpressionAttribute Class]
|
|
* https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments#optional-arguments[Named and Optional Arguments]
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
=== Message
|
|
|
|
Move "xxx" to the end of the parameter list.
|
|
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
=== on 18 Nov 2015, 10:01:25 Tamas Vajk wrote:
|
|
\[~ann.campbell.2] I modified the sample code: there can't be any parameter without a default value after parameters with default values. (So I added the ``++null++`` default value to the ``++message++``)
|
|
|
|
|
|
And also modified the last sentence. It is possible to not specify all parameters in a call, but then you force the callers of this method to use named arguments.
|
|
|
|
=== on 18 Nov 2015, 19:55:28 Ann Campbell wrote:
|
|
Okay, thanks [~tamas.vajk]
|
|
|
|
endif::env-github,rspecator-view[]
|