如何从C#(ASP.NET)中的函数返回多个值?

如何从C#(ASP.NET)中的函数返回多个值?,c#,C#,我有一个页面,用户在其中输入数字的一些产品和文本字段。我首先使用JavaScript计算总成本。根据他们输入的用户数量,他们会得到不同的费率(如下面的代码所示)。当用户在文本字段中键入或粘贴数字时,将调用函数CalculateCost,该函数调用其他函数(在示例中仅显示两个函数,CDCOst和DVDCost),以确保字段Monthly Cost和Year Cost显示的值正确 当然,在我插入数据库之前,我也想在代码背后做最后的计算。我怎样才能在C#中实现类似的目标 函数CDCost(){ var

我有一个页面,用户在其中输入数字的一些产品和文本字段。我首先使用JavaScript计算总成本。根据他们输入的用户数量,他们会得到不同的费率(如下面的代码所示)。当用户在文本字段中键入或粘贴数字时,将调用函数CalculateCost,该函数调用其他函数(在示例中仅显示两个函数,CDCOst和DVDCost),以确保字段Monthly Cost和Year Cost显示的值正确

当然,在我插入数据库之前,我也想在代码背后做最后的计算。我怎样才能在C#中实现类似的目标

函数CDCost(){ var monthlymount; var annualAmount; 风险价值金额; var users=$('#txtCD').val(); 如果(用户数>0&&用户数<100){ 金额=用户*14.95; 月金额=金额; 年平均数=月平均数*12; 返回[月数,年数]; } if(用户数>=100&&users 0&&users<100){ 金额=用户*16.95; 月金额=金额; 年平均数=月平均数*12; 返回[月数,年数]; } if(用户数>=100&&users 0&&users<100) { 金额=用户*14.95; 月金额=金额; 年平均数=月平均数*12; return//如何将此处的值返回到CalculateCost函数? } }
使用
out
参数,或者创建一个新类型,将您想要返回的所有东西包装起来(所谓的“属性包”):


您可以使用out参数返回多个值

您可以返回包含所有要返回的对象的集合(例如,双数组)或自定义对象

class MyCustomType
{
  double AnnualAmount{get; set;}
  double MonthlyAmount{get; set;}
}

// and in your function you could go
return new MyCustomType{ AnnualAmount = 4.5d, MonthlyAmount = 5.5d  };

最好的方法是返回一个包含值的字典

protected Dictionary<string, double> CDCost()
    {
        Dictionary<string,double> values = new Dictionary<string,double>();
        double monthlyAmount;
        double annualAmount;
        double amount;
        double users = Convert.ToDouble(txtCD.Text);

        if (users > 0 && users < 100)
    {
        amount = users * 14.95;
        values["monthlyAmount"] = amount;
        values["annualAmount"] = monthlyAmount * 12;
        return values
    }
受保护的字典CDCost()
{
字典值=新字典();
双月数;
双年轮山;
双倍金额;
双用户=Convert.ToDouble(txtCD.Text);
如果(用户数>0&&用户数<100)
{
金额=用户*14.95;
值[“MonthlyMount”]=金额;
数值[“年平均数”]=月平均数*12;
返回值
}

}您可以使用数组,如下所示:

protected double[] CDCost() {
    //a lot of code
    return new double[2] { annualAmount, monthlyAmount };
}
double cdCost = CDCost();
annualAmount = cdCost[0];
monthlyAmount = cdCost[1];
然后像这样使用它:

protected double[] CDCost() {
    //a lot of code
    return new double[2] { annualAmount, monthlyAmount };
}
double cdCost = CDCost();
annualAmount = cdCost[0];
monthlyAmount = cdCost[1];

将更改您现在执行此操作的方式,以返回CDCost对象:

public Class CDCost
{
  public double Monthly {get;set;}
  public double Annually {get return Monthly*12;}  

  public CDCost(double monthly)
  {
    Monthly=monthly;
  }
}

但是,如果你对c语法感兴趣,你可以使用
out
数组
(尽管我认为这两种方法在这种情况下都是糟糕的设计)。

NET 4中的元组类做得很好

protected Tuple<double, double, double, double> CDCost()
    {
        double monthlyAmount;
        double annualAmount;
        double amount;
        double users = Convert.ToDouble(txtCD.Text);
   if (users > 0 && users < 100)
    {
        amount = users * 14.95;
        monthlyAmount = amount;
        annualAmount = monthlyAmount * 12;
        return //how do I return the values here to a CalculateCost function?
    }
    return new Tuple<double, double, double, double>(monthlyAmount, annualAmount, amount, users);
}
受保护的元组CDCost()
{
双月数;
双年轮山;
双倍金额;
双用户=Convert.ToDouble(txtCD.Text);
如果(用户数>0&&用户数<100)
{
金额=用户*14.95;
月金额=金额;
年平均数=月平均数*12;
return//如何将此处的值返回到CalculateCost函数?
}
返回新元组(monthlyAmount、annualAmount、amount、users);
}

从技术上来说,答案是一个函数不能返回多个值。函数要么返回一个值,要么不返回任何值。这适用于您的Javascript示例——它实际上并没有返回两个值,而是返回一个值,即两个元素的数组

也就是说,正如其他人已经指出的那样,以下是您的选择:

1) 返回一个数组。这就是您在Javascript示例中所做的,它也可以在其他任何地方使用。我看到的问题有两个:一个,您被限制为一种类型(如果适用,还有它的子类型)。如果您想返回,比如说,一个double和一个string,您需要让它返回一个对象数组并转换为适当的类型。第二,这使得API的使用变得相当困难,因为排序至关重要。任何使用函数的代码都需要知道returnValue[0]表示每月金额,returnValue[1]表示年度金额。当然,您可以在文档中这样说,但使用它仍然是一个棘手的API。如果您(或其他人)出于某种原因(可能是粗心大意)更改了返回值的顺序,上帝会帮助您。这将是一个可怕的错误追踪

2) 还一本字典。这避免了排序问题,但它通过添加键问题来弥补这一问题——使用代码的任何人都需要知道返回的字典使用了一些特定的键集(例如,“monthlyAmount”和“annualAmount”)。输入错误,无论是在使用代码中还是在方法体中,都会让人头疼。就像数组解决方案一样,您必须确保记录键值。它还面临与阵列解决方案相同的类型问题。与阵列解决方案相比,它的性能也可能稍差一些,尽管它是否真的会产生显著的差异还值得怀疑

3)
out
参数。这避免了前面的问题,因为它们都可以是任何类型,并且编译器/IDE将捕获任何输入错误/错误的赋值。但是,通常我会尽量避免使用out参数(就像这样)。就个人而言,他们似乎滥用了参数语法——参数用于将数据传递到函数中,而out参数在技术上是这样做的,但用于返回值,而不是函数要使用的值。它还污染了方法签名——需要传递的参数越来越多,如果需要大量重载(并且没有使用.NET 4.0的可选/命名参数),这尤其令人讨厌。更为次要的是,这是一个bi
protected Tuple<double, double, double, double> CDCost()
    {
        double monthlyAmount;
        double annualAmount;
        double amount;
        double users = Convert.ToDouble(txtCD.Text);
   if (users > 0 && users < 100)
    {
        amount = users * 14.95;
        monthlyAmount = amount;
        annualAmount = monthlyAmount * 12;
        return //how do I return the values here to a CalculateCost function?
    }
    return new Tuple<double, double, double, double>(monthlyAmount, annualAmount, amount, users);
}
double outparam1, outparam2;
SomeFunction(out outparam1, out outparam2);
//use out parameters
Private iAmount  As Integer
Public ReadOnly Property Amount() As Integer
    Get
        Return iAmount
    End Get
End Property

Private iMonthlyAmount  As Integer
Public ReadOnly Property MonthlyAmount() As Integer
    Get
        Return iMonthlyAmount
    End Get
End Property

Private iAnnualAmount  As Integer
Public ReadOnly Property AnnualAmount() As Integer
    Get
        Return iAnnualAmount
    End Get
End Property
protected (double amount, double monthlyAmount, double annualAmount) CDCost()
    {
        double monthlyAmount;
        double annualAmount;
        double amount;
        double users = Convert.ToDouble(txtCD.Text);

        if (users > 0 && users < 100)
        {
            amount = users * 14.95;
            monthlyAmount = amount;
            annualAmount = monthlyAmount * 12;
            return (amount, monthlyAmount, annualAmount);
        }
        throw new NotImplementedException();
    }
    var (amount, monthlyAmount, annualAmount) = CDCost();