6.0版获得了nameof的新功能,但我不能理解它的目的,因为它只是接受变量名并在编译时将其更改为字符串。

我认为它在使用<T>时可能有一些目的,但当我尝试命名(T)时,它只是打印我一个T而不是使用的类型。

知道目的吗?


当前回答

nameof的另一个用例是检查标签页,而不是检查索引,你可以检查标签页的Name属性,如下:

if(tabControl.SelectedTab.Name == nameof(tabSettings))
{
    // Do something
}

不那么乱:)

其他回答

之前我们使用的是这样的东西:

// Some form.
SetFieldReadOnly( () => Entity.UserName );
...
// Base form.
private void SetFieldReadOnly(Expression<Func<object>> property)
{
    var propName = GetPropNameFromExpr(property);
    SetFieldsReadOnly(propName);
}

private void SetFieldReadOnly(string propertyName)
{
    ...
}

原因-编译时安全。没有人可以默默地重命名属性并破坏代码逻辑。现在我们可以使用nameof()。

假设您需要在代码中打印一个变量的名称。如果你这样写:

int myVar = 10;
print("myVar" + " value is " + myVar.toString());

然后如果有人重构代码并使用另一个名称myVar,他/她将不得不在你的代码中寻找字符串值并相应地更改它。

相反,如果你这样写:

print(nameof(myVar) + " value is " + myVar.toString());

这将有助于自动重构!

nameof的另一个用例是检查标签页,而不是检查索引,你可以检查标签页的Name属性,如下:

if(tabControl.SelectedTab.Name == nameof(tabSettings))
{
    // Do something
}

不那么乱:)

它对ArgumentException及其衍生物非常有用:

public string DoSomething(string input) 
{
    if(input == null) 
    {
        throw new ArgumentNullException(nameof(input));
    }
    ...

现在,如果有人重构输入参数的名称,异常也将保持最新。

在以前必须使用反射来获取属性或参数名称的某些地方,它也很有用。

在你的例子中,nameof(T)获取类型参数的名称-这也很有用:

throw new ArgumentException(nameof(T), $"Type {typeof(T)} does not support this method.");

nameof的另一种用法是用于枚举——通常如果你想要枚举的字符串名称,你可以使用.ToString():

enum MyEnum { ... FooBar = 7 ... }

Console.WriteLine(MyEnum.FooBar.ToString());

> "FooBar"

这实际上相对较慢,因为. net保存枚举值(即7)并在运行时查找名称。

用nameof代替:

Console.WriteLine(nameof(MyEnum.FooBar))

> "FooBar"

现在。net在编译时将枚举名称替换为字符串。


还有一种用法是INotifyPropertyChanged和日志记录——在这两种情况下,你都想把你调用的成员的名字传递给另一个方法:

// Property with notify of change
public int Foo
{
    get { return this.foo; }
    set
    {
        this.foo = value;
        PropertyChanged(this, new PropertyChangedEventArgs(nameof(this.Foo));
    }
}

还是……

// Write a log, audit or trace for the method called
void DoSomething(... params ...)
{
    Log(nameof(DoSomething), "Message....");
}

nameof关键字的用法之一是在wpf中以编程方式设置Binding。

要设置绑定,你必须设置路径字符串和nameof关键字,可以使用重构选项。

例如,如果你在你的UserControl中有IsEnable依赖属性,你想把它绑定到你的UserControl中某些复选框的IsEnable上,你可以使用这两个代码:

CheckBox chk = new CheckBox();
Binding bnd = new Binding ("IsEnable") { Source = this };
chk.SetBinding(IsEnabledProperty, bnd);

and

CheckBox chk = new CheckBox();
Binding bnd = new Binding (nameof (IsEnable)) { Source = this };
chk.SetBinding(IsEnabledProperty, bnd);

很明显,第一个代码不能重构,但第二个代码……