Daily Knowledge Drop
With C# 11 (coming towards the end of this year) the scope of the nameof
expression is being extended, allowing it to be used inside an attribute expression
.
Below examples written and tested using .NET 7-preview5, and as such may differ from the final release or subsequent preview releases.
Sample
In the examples below, a simple Attribute
which takes a single string in the constructor is used:
[AttributeUsage(AttributeTargets.Method)]
public class MethodAttr : Attribute
{
private readonly string _parameterName;
// constructor just takes a string
public MethodAttr(string parameterName)
{
_parameterName = parameterName;
}
}
Suppose we want to apply this attribute to a method, and specify the method parameter name as the argument to the Attribute constructor
.
Below we'll look at how this is done prior to C# 11 and how it can be improved on with C# 11.
Pre C# 11
Prior to C #11 when using the attribute, the parameter name had to be hardcoded into the MethodAttr constructor
:
public class NameOfClass
{
public NameOfClass()
{
Console.WriteLine($"In constructor of {nameof(NameOfClass)}");
}
public void NameOfMethod()
{
Console.WriteLine($"In method {nameof(NameOfMethod)}");
}
// method parameter name hardcoded into the MethodAttr constructor
[MethodAttr("The parameter name is 'stringParam'")]
public void MethodWithParam(string stringParam)
{
// however, in the method nameof can be used to get
// the name of the parameter
Console.WriteLine($"Value of parameter '{nameof(stringParam)}' is " +
$"is {stringParam}");
}
}
The nameof
expression can be used successfully on the parameter name in the method (nameof(stringParam)
), however when it comes to the attribute, the name has to be hardcoded - the nameof
expression cannot be used in this context.
The issue with this approach, is that if the variable stringParam is renamed (either with F2, or CTRL R+R) then all string value representations
of the variable name (such as in the attribute constructor) need to manually be updated
. With nameof
, a rename will ensure that all references (including the nameof
references) are renamed - this results in a more consistent and accurate code base.
Prior to C# 11, there was no choice but to use the string value in the attribute - however this changes in C# 11.
C# 11
With C# 11, the scope of nameof
has been increased, and it can now be used in attribute parameters:
public class NameOfClass
{
public NameOfClass()
{
Console.WriteLine($"In constructor of {nameof(NameOfClass)}");
}
public void NameOfMethod()
{
Console.WriteLine($"In method {nameof(NameOfMethod)}");
}
// method parameter name hardcoded into the MethodAttr constructor
[MethodAttr($"The parameter name is '{nameof(stringParam)}'")]
public void MethodWithParam(string stringParam)
{
// however, in the method nameof can be used to get
// the name of the parameter
Console.WriteLine($"Value of parameter '{nameof(stringParam)}' is " +
$"is {stringParam}");
}
}
Now, nameof
can be used in the method as well as in the attribute parameter!
Notes
A small, but welcome change - leveraging nameof
results in more consistent, more accurate and safer code. It's not possible to change the name of the variable, without changing all reference to it also being updated - otherwise a compiler error will occur. The more places nameof
can be utilized, the better!
References
Daily Drop 152: 02-09-2022
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.On This Page