You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#:如何在父类方法中获取子类传入的动态命名参数?

在C#父类方法中获取子类调用时的命名参数名称与值

你需要在父类Base的Get方法中,获取子类(如User、Task)调用该方法时传入的命名参数名称和对应值,尝试过params dynamic[] values但只能拿到值,无法获取参数名,以下是几种可行的实现方案:

方案1:使用匿名类型+反射

利用匿名类型的属性名与调用时的命名参数名一致的特性,结合反射提取参数名和对应值,调用语法最接近你的原始需求:

class Base
{
    public dynamic Get(object parameters)
    {
        if (parameters == null)
            return null;
        
        // 构建参数名-值的字典
        var paramDict = new Dictionary<string, dynamic>();
        foreach (var prop in parameters.GetType().GetProperties())
        {
            paramDict[prop.Name] = prop.GetValue(parameters);
        }

        // 这里可以直接使用paramDict处理参数
        foreach (var kvp in paramDict)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
        
        return null; // 根据业务需求返回对应内容
    }
}

class User : Base
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Password { get; set; }
    
    public void Init()
    {
        // 调用时仅需给参数套上new {}
        this.Get(new { Id = 5, Name = "admin", Password = "admin" });
    }
}

class Task : Base
{
    public int Id { get; set; }
    public string Name { get; set; }
    
    public void Init()
    {
        this.Get(new { Id = 1, Name = "task1" });
    }
}

方案2:直接传递Dictionary<string, dynamic>

跳过反射,直接用字典传递键值对,性能更优,适合对性能敏感的场景:

class Base
{
    public dynamic Get(Dictionary<string, dynamic> parameters)
    {
        if (parameters == null)
            return null;
        
        // 直接使用字典中的参数名和值
        foreach (var kvp in parameters)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
        
        return null;
    }
}

class User : Base
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Password { get; set; }
    
    public void Init()
    {
        this.Get(new Dictionary<string, dynamic>
        {
            { "Id", 5 },
            { "Name", "admin" },
            { "Password", "admin" }
        });
    }
}

方案3:C# 10+ 使用CallerArgumentExpression(适合固定少量参数)

利用C# 10引入的CallerArgumentExpression属性自动获取参数名,但需要为不同参数数量编写重载,扩展性有限:

using System.Runtime.CompilerServices;

class Base
{
    // 单个参数的版本
    public dynamic Get<T>(T value, [CallerArgumentExpression("value")] string paramName = "")
    {
        Console.WriteLine($"{paramName}: {value}");
        return null;
    }

    // 两个参数的版本
    public dynamic Get<T1, T2>(T1 value1, T2 value2,
        [CallerArgumentExpression("value1")] string paramName1 = "",
        [CallerArgumentExpression("value2")] string paramName2 = "")
    {
        Console.WriteLine($"{paramName1}: {value1}");
        Console.WriteLine($"{paramName2}: {value2}");
        return null;
    }
}

class Task : Base
{
    public int Id { get; set; }
    public string Name { get; set; }
    
    public void Init()
    {
        this.Get(Id = 1, Name = "task1");
    }
}

方案对比

  • 匿名类型+反射:调用语法简洁直观,接近原始需求,但依赖反射,性能略低,适合大多数业务场景。
  • Dictionary传参:无反射开销,性能更优,但调用时需要手动构建键值对,写法稍繁琐。
  • CallerArgumentExpression:无需反射,但需要为不同参数数量编写重载,扩展性差,仅适合参数数量固定的场景。

为什么params dynamic[]无法获取参数名

params dynamic[]本质是将传入的参数打包成数组,而命名参数只是编译阶段的语法提示,编译后参数名称不会被保留到数组中,因此无法通过这种方式获取参数名。

内容的提问来源于stack exchange,提问作者zohaib yousaf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 11:35:24