{CallerMemberName}类似于nameof()参数的功能

时间:2018-06-21 05:53:11

标签: c# .net attributes method-signature

我正在编写更多的库代码,并且遇到了麻烦-这是一个示例

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));
}

基本上我必须在用法中输入名称

我想拥有的是:

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);
}

有更好的方法吗?在WPF时代,我曾经像这样使用[CallerMemberName]:

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

有人知道类似的方法可以达到相同的结果吗?考虑到该库的调用频率,我不介意进入构建后步骤或其他任何步骤,但出于性能原因,宁愿避免反射。

编辑-使目标更清晰

1 个答案:

答案 0 :(得分:1)

首先,我个人还是不会这样做,您将逻辑隐藏在另一种方法中以节省两次击键。为此,对于新读者来说,他们将不得不单击以查看其作用,并且仍然必须使用nameof

您可能可以做一些反思,但是即使如此,要获得可疑的收益也将是很多工作。

我可以建议第三种方法吗?

为什么不只为关键字args [tab]

创建一个Resharper模板?
$NAME$ = $NAME$ ?? throw new ArgumentNullException(nameof($NAME$));

好处是

  • 新读者可以轻松了解最新情况。
  • 您只有很少的击键,因为它会在几个字母之后提示输入类型
  • 您保存一点IL和对堆栈的调用

如果您使用Resharper,请签出Code Annotation Attributes


我猜你也可以使用一个表达式

示例

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

用法

ExampleFunction(x => WhatIsMyName);

依我之见,什么都没有得到