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

如何将含多类型不定参数的JavaScript函数转换为C#风格?

C#实现支持多类型不定参数的RPN计算器

核心思路

C#是强类型语言,无法直接使用JavaScript的any类型接收任意参数,但可以通过params object[]接收不定长度的多类型参数列表,再通过类型判断分别处理三种参数:

  • 自定义类实例:提取其NominalValue属性值
  • 数值类型(int、double等):直接转换为double存入栈
  • 字符串运算符:执行对应的栈运算

实现代码

首先定义对应原JS逻辑的自定义类:

public class VariableUnitBuilder
{
    public double NominalValue { get; set; }
    // 其他业务属性和方法
}

然后实现RPN计算器方法:

public class FxMath
{
    public void RPN(VariableUnitBuilder ergebnis, params object[] seq)
    {
        var stack = new Stack<double>();
        int i = 0;

        // 初始化栈:处理第一个参数
        if (seq.Length > 0)
        {
            stack.Push(GetNumericValue(seq[i]));
            i++;
        }

        while (i < seq.Length)
        {
            var item = seq[i];
            if (TryGetNumericValue(item, out double numericVal))
            {
                stack.Push(numericVal);
            }
            else
            {
                // 处理运算符
                var op = item.ToString();
                if (stack.Count < 2)
                    throw new InvalidOperationException("栈中元素不足,无法执行二元运算");

                double a = stack.Pop();
                double b = stack.Pop();
                double calcResult = op switch
                {
                    "+" => b + a,
                    "-" => b - a,
                    "*" => b * a,
                    "/" => b / a,
                    _ => throw new NotSupportedException($"不支持的运算符: {op}")
                };
                stack.Push(calcResult);
            }
            i++;
        }

        // 将最终结果赋值给传入的结果对象
        if (stack.Count > 0)
            ergebnis.NominalValue = stack.Pop();
    }

    // 提取数值的辅助方法(抛出异常版本)
    private double GetNumericValue(object item)
    {
        if (!TryGetNumericValue(item, out double value))
            throw new ArgumentException($"无法从类型{item.GetType().Name}中提取数值");
        return value;
    }

    // 提取数值的辅助方法(返回bool版本)
    private bool TryGetNumericValue(object item, out double value)
    {
        value = 0;
        switch (item)
        {
            case VariableUnitBuilder vub:
                value = vub.NominalValue;
                return true;
            case int intVal:
                value = intVal;
                return true;
            case double doubleVal:
                value = doubleVal;
                return true;
            case float floatVal:
                value = floatVal;
                return true;
            case long longVal:
                value = longVal;
                return true;
            // 可根据需要扩展更多数值类型
            default:
                return false;
        }
    }
}

使用示例

按照你给出的调用方式直接使用即可:

// 假设Mt、L、F都是VariableUnitBuilder的实例
this.FxMath.RPN(this.Mt, this.L, 2, "*", this.F, "*");

关键细节说明

  • params object[] seq:C#中实现不定参数的标准方式,允许方法接收任意数量、任意类型的参数
  • 类型判断:通过is模式匹配和switch语句,清晰区分不同类型的参数,符合C#强类型特性
  • 运算符处理:使用C# 8.0+的switch表达式,比传统switch语句更简洁易读
  • 异常处理:针对栈元素不足、不支持的运算符等情况抛出明确异常,便于调试

内容的提问来源于stack exchange,提问作者Juergen Gross

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:37:25