C# 通过引用传递一个变量和;“返回”;两个变量

C# 通过引用传递一个变量和;“返回”;两个变量,c#,pass-by-reference,C#,Pass By Reference,所以我试图传入一个变量,money变量,并将其分解为两个变量。当我只传递了一个值时,我陷入了困境,试图找出如何传递回两个值。我应该从用户那里得到一个双倍值的钱,并把它分成两个int值。例如,我得到一个像3.45这样的值,然后将其拆分并打印出消息,“3.45美元中有3美元45美分”。我理解通过引用传递,但我只是想弄明白,就像我说的,如何得到两个变量。我只能将money变量传递给方法 我知道我的程序不对。只是想了解一些关于如何做到这一点的想法和解释。谢谢 using System; stati

所以我试图传入一个变量,money变量,并将其分解为两个变量。当我只传递了一个值时,我陷入了困境,试图找出如何传递回两个值。我应该从用户那里得到一个双倍值的钱,并把它分成两个int值。例如,我得到一个像3.45这样的值,然后将其拆分并打印出消息,“3.45美元中有3美元45美分”。我理解通过引用传递,但我只是想弄明白,就像我说的,如何得到两个变量。我只能将money变量传递给方法 我知道我的程序不对。只是想了解一些关于如何做到这一点的想法和解释。谢谢

 using System;

 static class Program
 {
      //Declare any constansts
      const int ONE_HUNDRED = 100;

     static void Main()
     {
         //Declare local variables
         double money = 0;

         //Ask the user to input a money value
         Console.WriteLine("Please enter a money value. (ex. 2.95)");

         //Store the value in a variable
          money = double.Parse(Console.ReadLine());

          //Take the variable and call the SplitMoney method
          SplitMoney(ref money);

          //Display the message
          Console.WriteLine("There are {0:d} and {1:d} cents in ${0:f2}", money, dollars cents);

          Console.ReadLine();
     }//End Main()

      //Split Money Method
      //Purpose: To split the money into dollars and cents
      //Parameters: One double passed by reference
      //Returns: Nothing
      static void SplitMoney(ref double money)
      {
            money = (int)(money * ONE_HUNDRED);
            int dollars = (int)(money / ONE_HUNDRED);
            int cents = (int)(money % ONE_HUNDRED);
      }
   }//End class Program
关于你的问题:

public class SplittedMoney
{
    public int Dollars { get; set; }
    public int Cents { get; set; }
}
你把它还给我。那将是最简单的方法

更好的方法可能是:

public struct SplittedMoney
{
    public readonly int Dollars;
    public readonly int Cents;

    public SplittedMoney(int dollars, int cents)
    {
        Dollars = dollars;
        Cents = cents;
    }
}
这样更好,因为分割的美元仍然是一个值,所以使用不可变结构是一种方法

现在,不要在任何需要精确十进制计算的情况下使用
double
s。使用
decimal
s,因为它们是为该任务而设计的。
double
在基数为10时可能会失去精度,因为它是在基数为2时存储和操作的。十进制设计用于保持以10为基数的精度


下面是使用上述结构重写的
SplitMoney

  static SplittedMoney SplitMoney(decimal money)
  {
        var totalCents = (int)(money * 100);
        int dollars = (int)(totalCents / 100);
        int cents = (int)(totalCents % 100);
        return new SplittedMoney(dollars, cents);
  }

嗯,
SplitMoney
当前返回0个值。您可以继续变异
money
以仅包含美元值,然后实际从该方法返回
cents

  static int SplitMoney(ref double money)
  {
        money = (int)(money * ONE_HUNDRED);
        int dollars = (int)(money / ONE_HUNDRED);
        int cents = (int)(money % ONE_HUNDRED);
        return cents;
  }
然后,当您使用它时:

var moneyCents = SplitMoney(ref money);
Console.WriteLine("money = {0:f2}.{1:f2}", money, moneyCents);

更好的是,您可以返回一个包含
美元和
美分的元组:

  static Tuple<int,int> SplitMoney(double money)
  {
        var totalCents = (int)(money * ONE_HUNDRED);
        int dollars = (int)(money / ONE_HUNDRED);
        int cents = (int)(money % ONE_HUNDRED);
        return Tuple.Create(dollars,cents);
  }

我应该注意到,
SplittedMoney
可能应该被重写为一个纯函数(不会对超出其范围的值进行变异),它返回一个
SplittedMoney
对象,如Lucas在回答中所述。我的解决方案只需要对你的代码做一点小改动。实际上你的想法行不通。我的语句是Console.Writeline(“在{3:f2中有{0:d}美元和{1:d}美分)”,money,dollars,cents);在这种情况下,
SplittedMoney
的答案肯定是正确的。这种方法的问题是,由于您在方法中对该变量进行了变异,原始货币值不再可用。您还有其他想法吗?我假设使用double,并且没有使用结构。我刚刚添加了一个实现返回2元组的
SplitMoney
为什么要使用浮点数?您可以重写类,使
美元
美分
都是
整数
。这将更难操作。
系统。十进制
就是为了解决这个问题而设计的。使用
十进制
表示
美元
意味着您可以使用分数美元,但您的结构在
美分
字段中已经表示了分数美元。这有点奇怪
美分
也是如此。使用分数美分有意义吗?在这个问题中,您将看到美分表示为
int
。一点也不粗鲁。此外,我还添加了一个
SplitMoney
的实现,它会在您的答案中返回一个
SplittedMoney
。重复的问题涵盖了许多可能返回多个值的方法-如果不包括您需要的方法,请随意选择您喜欢的或选择新问题(返回
Tuple
,返回自定义类型,使用
out
/
ref
返回每个结果)数组通常是最简单的:
static int[]SplitMoney(十进制货币){return new[]{(int)(money/100),(int)(money%100)}
var splitMoney = SplitMoney(money);
Console.WriteLine("money = {0:f2}.{1:f2} from {2:d}",
    splitMoney.Item1, splitMoney.Item2, money);