Xsjado
Xsjado

Reputation: 367

{CallerMemberName} like Functionality for nameof() param

I'm writing more library code and came across an annoyance - here is an example

public static TParam RequiredParam<TParam>(TParam param, string name) where TParam : class 
{
  return param ?? throw new ArgumentNullException(name);
}

private readonly int _testInt;

public TestClass(int testInt)
{
  _testInt = RequiredParam(testInt, nameof(testInt));
}

Basically I have to pass in the name in the usage

What I want to have is:

public static TParam RequiredParam<TParam>(TParam param) where TParam : class 
{
  return param ?? throw new ArgumentNullException(*NAME STILL GETS HERE SOMEHOW*);
}

private readonly int _testInt;

public TestClass(int testInt)
{
  _testInt = RequiredParam(testInt);
}

Is there a better way? Back in the days of WPF I used to use [CallerMemberName] like so:

private void PropertyChanged([CallerMemberName]string name = default)
{
  PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}

Does anyone know something similar to achieve the same result for this? Considering how often this library is called I don't mind stepping into post-build steps or whatever, but would prefer to avoid reflection for performance reasons.

Edit - Made my objective clearer

Upvotes: 0

Views: 156

Answers (1)

TheGeneral
TheGeneral

Reputation: 81513

Firstly, i personally wouldn't do that anyway, you are hiding logic behind another method to save a couple of keystrokes. In doing this, for new readers they will have to click through to see what it does, and you still have to use nameof anyway.

You could probably do something with reflection, but even then it will be a lot of work for dubious gain.

Can i suggest a 3rd approach?

Why don't you just create a Resharper template for the keywords args[tab]

$NAME$ = $NAME$ ?? throw new ArgumentNullException(nameof($NAME$));

The benefits are

  • New readers can easily see whats going on.
  • You only have minimal key strokes as it will suggest the type after a few letters
  • You save a bit of IL and a call to the stack

Also if you use Resharper, check out Code Annotation Attributes


You could also use an expression i guess

Example

public void ExampleFunction(Expression<Func<string, string>> f) {
    Console.WriteLine((f.Body as MemberExpression).Member.Name);
}

Usage

ExampleFunction(x => WhatIsMyName);

Still in my opinion, nothing is really gained

Upvotes: 1

Related Questions