C#中可能被遗忘的“nameof表达式”

    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,所以输出相同,这里就不列出

代码生成后反编译的结果:

d3a64f90be78a2c8eb3b1f44d4924d2a.png

从反编译的结果可以看出,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编程大全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值