SW 随笔 007 — C# 10/.NET6 CallerArgumentExpression 案例

声明:个人笔记,概不负责

参考文章: .NET6新东西--CallerArgumentExpression
参考摘要:

在.NET6以前我们如果要获取调用方的信息可以使用这三个Caller Info Attribute:

  1. CallerMemberName:调用方名称,方法名或者属性名;
  2. CallerFilePath:调用方源代码的位置;
  3. CallerLineNumber:调用方位于源代码的第几行。
  4. 新增的CallerArgumentExpression也是一种caller info,一般会用它来自动获取传进来的参数表达式

本文开始:

上文中的例子实在没有说服力,官方英文文档[1] 也实在是没看懂。官方实际的人话在这里[2]

Attribute Description Type
CallerArgumentExpressionAttribute String representation of the argument expression. String

经过和 Copilot 反复掰扯,实际意思如下, …… 上代码!


class DemoBoard
{
    // C# 10/.NET 6 get the argument expression (实参表达式) for parameter (形参)
    //
    // 英文里, argument  表示 "实参"
    //        parameter 表示 "形参"
    //
    public static byte SlaveAddr(
        object? dummy,            // parameter (形参)
        [CallerArgumentExpression(nameof(dummy))] string? argExpr = null  // 捕获 argument (实参)
        )
    {
        Debug.WriteLine(argExpr);
        byte addr = 1;
        return addr;

        // 从 实参 推算 另一个值, 可以用 Attribute 反射, 也可以用 查表, .. (随心所欲)
        //
        // addr = GetAddressFromAttribute(argExpr)
    }

    public DemoBoard()
    {
        IoExp = new IoExpander(SlaveAddr(IoExp));        // argument (实参) 为 IoExp
        IoExp2 = new IoExpander(SlaveAddr(this.IoExp2)); // argument (实参) 为 this.IoExp2

        // 为什么是  argument expression (实参表达式) ?
        //  
        // 因为 caller 可以在 形参 的位置, 传入表达式
        //
        // 所以, [CallerArgumentExpression] 类似某种 源代码级 的反射
        // 可以 倒吐出 形参 位置, 实际填充的 源代码
        //
        // 所以, [CallerArgumentExpression] 标注的类型为 string
        //
        // 所以, 实际在处理 argExpr 时, 需要 防御式 清理字符串
        // 因为, 主要是 源自帮助 Debug 目的这一脉,
        // 所以, 也不用太激动, 洒洒水(大概) 防御一下就行. 你又不是写编译器, 你看看它的全名
        //
        //  System.Runtime.CompilerServices.CallerArgumentExpressionAttribute
        //
    }

    // 此处用 Attribute 注入,帅的一逼啊
    //
    [Slave7bitAddress(0x20, "[U1004] 7bitAddress = 0x20 | Write= 0x40 | Read= 0x41")]
    readonly IoExpander IoExp;

    [Slave7bitAddress(0x21, "[U1005] 7bitAddress = 0x21 | Write= 0x42 | Read= 0x43")]
    readonly IoExpander IoExp2;

}

class IoExpander
{
    public IoExpander(byte Addr)
    {
    }
}

  1. https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute?view=net-10.0 ↩︎

  2. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/attributes/caller-information?redirectedfrom=MSDN ↩︎

posted @ 2026-04-01 09:02  悠洋洋  阅读(2)  评论(0)    收藏  举报