6.0版获得了nameof的新功能,但我不能理解它的目的,因为它只是接受变量名并在编译时将其更改为字符串。
我认为它在使用<T>时可能有一些目的,但当我尝试命名(T)时,它只是打印我一个T而不是使用的类型。
知道目的吗?
6.0版获得了nameof的新功能,但我不能理解它的目的,因为它只是接受变量名并在编译时将其更改为字符串。
我认为它在使用<T>时可能有一些目的,但当我尝试命名(T)时,它只是打印我一个T而不是使用的类型。
知道目的吗?
当前回答
我能想到的最常见的用例是使用INotifyPropertyChanged接口时。(基本上所有与WPF和绑定相关的东西都使用这个接口)
看看这个例子:
public class Model : INotifyPropertyChanged
{
// From the INotifyPropertyChanged interface
public event PropertyChangedEventHandler PropertyChanged;
private string foo;
public String Foo
{
get { return this.foo; }
set
{
this.foo = value;
// Old code:
PropertyChanged(this, new PropertyChangedEventArgs("Foo"));
// New Code:
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Foo)));
}
}
}
正如您可以看到的,在旧的方法中,我们必须传递一个字符串来指示哪个属性已经更改。使用nameof,我们可以直接使用属性的名称。这可能看起来没什么大不了的。但是想象一下如果有人改变了属性Foo的名字会发生什么。当使用字符串时,绑定将停止工作,但编译器不会警告你。当使用nameof时,你会得到一个编译器错误,没有名称Foo的属性/参数。
请注意,有些框架使用一些反射魔法来获取属性的名称,但现在我们不再需要nameof this了。
其他回答
我能想到的最常见的用例是使用INotifyPropertyChanged接口时。(基本上所有与WPF和绑定相关的东西都使用这个接口)
看看这个例子:
public class Model : INotifyPropertyChanged
{
// From the INotifyPropertyChanged interface
public event PropertyChangedEventHandler PropertyChanged;
private string foo;
public String Foo
{
get { return this.foo; }
set
{
this.foo = value;
// Old code:
PropertyChanged(this, new PropertyChangedEventArgs("Foo"));
// New Code:
PropertyChanged(this, new PropertyChangedEventArgs(nameof(Foo)));
}
}
}
正如您可以看到的,在旧的方法中,我们必须传递一个字符串来指示哪个属性已经更改。使用nameof,我们可以直接使用属性的名称。这可能看起来没什么大不了的。但是想象一下如果有人改变了属性Foo的名字会发生什么。当使用字符串时,绑定将停止工作,但编译器不会警告你。当使用nameof时,你会得到一个编译器错误,没有名称Foo的属性/参数。
请注意,有些框架使用一些反射魔法来获取属性的名称,但现在我们不再需要nameof this了。
nameof的另一个用例是检查标签页,而不是检查索引,你可以检查标签页的Name属性,如下:
if(tabControl.SelectedTab.Name == nameof(tabSettings))
{
// Do something
}
不那么乱:)
ASP。NET核心MVC项目使用AccountController.cs和ManageController.cs中的name和RedirectToAction方法来引用控制器中的动作。
例子:
return RedirectToAction(nameof(HomeController.Index), "Home");
这句话的意思是:
return RedirectToAction("Index", "Home");
和takes将用户带到'Home'控制器中的'Index'动作,即/Home/Index。
c# 6.0的nameof特性的另一个用例变得很方便——考虑像Dapper这样的库,它使数据库检索变得更容易。虽然这是一个很棒的库,但您需要在查询中硬编码属性/字段名。这意味着如果你决定重命名你的属性/字段,你很有可能会忘记更新查询来使用新的字段名。使用字符串插值和特性名称,代码变得更容易维护和类型安全。
从链接中给出的例子
没有nameof
var dog = connection.Query<Dog>(
"select Age = @Age, Id = @Id",
new {Age = (int?) null, Id = guid});
与nameof
var dog = connection.Query<Dog>(
$"select {nameof(Dog.Age)} = @Age, {nameof(Dog.Id)} = @Id",
new {Age = (int?) null, Id = guid});
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);
很明显,第一个代码不能重构,但第二个代码……