C#每升级一个版本都会增加新的特性,又要继续学习,感觉身体被掏空。但是不是每个特性都实用,有的语法可能用上几次就渐渐淡忘了。前几天使用反射,发现一个跟反射有类似功能的关键字“nameof”表达式,居然遗忘了。本文将替大家回顾一下nameof表达式。
1、nameof表达式
nameof表达式是C# 6.0引入的一项功能。nameof 表达式可生成变量、类型或成员的名称作为字符串常量。nameof 表达式在编译时进行求值,在运行时无效。nameof是编译时进行求值,而在运行时无效,恰好跟反射相反。我们用下面案例与反射对比看看编译后的效果。
//OfName获取名称
string nameOfName = nameof(TestClass);
//反射获取名称
Type type = typeof(TestClass);
string typeName = type.Name;
Console.WriteLine($"OfName获取名称:{nameOfName}");
Console.WriteLine($"反射获取名称:{typeName}");
//类名都是TestClass,所以输出相同,这里就不列出
代码生成后反编译的结果:
从反编译的结果可以看出,nameOf关键字消失了(红框处),取而代之的结果,而反射由于是运行时编译,所以代码没有变化。
2、nameOf表达式的使用
可以让变量、类型或成员的名称作为字符串常量。代码示例如下:
Console.WriteLine(nameof(System.Collections.Generic)); // output: Generic
Console.WriteLine(nameof(List<int>)); // output: List
Console.WriteLine(nameof(List<int>.Count)); // output: Count
Console.WriteLine(nameof(List<int>.Add)); // output: Add
var numbers = new List<int> { 1, 2, 3 };
Console.WriteLine(nameof(numbers)); // output: numbers
Console.WriteLine(nameof(numbers.Count)); // output: Count
Console.WriteLine(nameof(numbers.Add)); // output: Add
//代码来源:微软官网
可以看出它能获得变量、类型或成员的名称,并以字符串展现。
它可以用于异常消息的创建,让异常更准确捕获错误的来源。
还可以监测属性的更改,下面的案例将展示属性更改的检查。如下:
using System;
public class Program
{
public static void Main()
{
Person person = new Person();
// 订阅属性更改事件
person.PropertyChanged += (sender, propertyName) =>
{
Console.WriteLine($"属性 {propertyName} 已更改。");
};
// 修改属性值,触发事件
person.Name = "欢迎关注公众号DotNET开发跳槽";
Console.ReadLine();
}
}
public class Person
{
private string name;
public string Name
{
get { return name; }
set
{
if (name != value)
{
name = value;
OnPropertyChanged(nameof(Name));
}
}
}
public event EventHandler<string> PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, propertyName);
}
}
//只要赋值会通过事件输出:属性Name已更改。
从 C# 11 开始,可以在方法或其参数的属性 中使用具有方法参数的 nameof 表达式。
结语
总的来说nameof 表达式也是C#的语法糖之一。它是编译时求值,可以在与反射相同的时功能替换反射,这样可以提高代码的性能,质量和可读性,当然也可以避免AOT发布出现的部分反射问题。尽管很少使用nameof表达式,但是它也是C#比较牛逼的语法糖。
大家还记得nameof 表达式吗?对它有什么看法?欢迎留言讨论。希望本文对大家有所收获,同时欢迎关注dotnet开发跳槽的其它文章。
参考:
微软官方文档:
learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/nameof
-技术群:添加小编微信并备注进群
小编微信:mm1552923 公众号:dotNet编程大全