【问题标题】:pass by ref C# button_on_click通过 ref C# button_on_click
【发布时间】:2018-10-18 14:39:47
【问题描述】:

我正在创建一个捐赠应用程序,它读取文本框中的输入,将其转换为双精度。然后使用operatingCost的方法,它应该把转换后的两倍除以17%(营业费)。目前在该方法中,我有变量dontationBFees 进来,然后除以17 并创建一个新变量afterFees。我遇到的问题是我需要在这个项目中通过 ref 传递,我似乎无法访问 afterFees 变量。我需要获取 ref afterFees 并将其显示给我的 afterFeesBox。我的按钮on_click 也有这个方法。任何帮助将不胜感激。以下是我的代码:

   private Double donationBFees = 0;


    private void button1_Click(object sender, EventArgs e)
    {
        String donationBeforeFees;
        Double aFees;
        String totalDonationRaised;

        donationBeforeFees = donationBox.Text;
        donationBFees = System.Convert.ToDouble(donationBeforeFees);

        void operatingCost(ref double afterFees)
        {
            afterFees = (donationBFees / 17);
        }


        afterFeesBox.Text = operatingCost(ref afterFees);


    }

【问题讨论】:

  • 你如何/在哪里声明afterFees
  • 旁注:对于货币价值,使用decimal:stackoverflow.com/questions/1165761/…
  • 重构建议:将您的void operatingCost(ref double afterFees) 方法放在您的点击事件方法之外。顺便提一句。它返回void - 您不能以这种方式将其分配给文本属性。我会执行以下操作:将您的方法更改为 double operatingCost(double fees)afterFees = operatingCost(donationBFees) 一样调用它 - 不需要参考。一切未经测试,请检查它是否仍然是您想要的输出!
  • “我需要在这个项目中通过 ref” - 为什么?
  • @Greg 我在方法中声明了 afterFees,它也在那里创建。

标签: c# onclick pass-by-reference


【解决方案1】:

一些(希望有帮助的)事情:

void operatingCost(ref double afterFees)
{
    afterFees = (donationBFees / 17);
}

这意味着您正在传递对afterFees 的引用,并且在方法中对afterFees 执行操作(在这种情况下,将其分配给donationBFees / 17),并且不返回任何内容。但是,这一行:

afterFeesBox.Text = operatingCost(ref afterFees);

表示您将Text 分配给该方法的结果,这不起作用,因为它的返回类型是void

你也永远不会声明afterFees,除非在那个方法中(它不起作用)。我想您会收到错误消息“名称...在当前上下文中不存在。”您需要在本地声明此变量(并将其重命名为不冲突):

double partAfterFees = 0;
operatingCost(ref partAfterFees);

所以你可以做几件事:

1) 返回一个类型(您当前使用的是double,但正如 cmets 中所建议的,可能需要使用decimal)。然后,您可以根据需要删除 ref。然后您可以执行以下操作:

double operatingCost(ref double afterFees)
{
    afterFees = (donationBFees / 17);
    return afterFees;
}
afterFeesBox.Text = operatingCost(ref partAfterFees).ToString();

但这似乎很奇怪,所以我可能会这样做(鉴于你所说的):

double partAfterFees = 0;
operatingCost(ref partAfterFees);
afterFeesBox.Text = partAfterFees.ToString();

请注意,有一些“更好”的解决方案涉及重构和检查有效输入等。但我认为这可以回答您的问题。

【讨论】:

  • 谢谢 Greg,我更改了代码中的一些内容。我注意到(在帮助下)我的百分比计算在哪里。我通过反复试验解决了这个问题,现在它可以工作了。我也按照建议改为十进制而不是双精度。
【解决方案2】:

调用 byref 会更改传递给函数的值,因此您需要传入一个您不介意更改的变量。

在这个例子中,我有两个叫做 afterFees 的东西,所以我重命名了一个,以表明一个是参数。

private Double donationBFees = 0;

void operatingCost(ref double afterFeesParam)
{
    afterFeesParam = (afterFeesParam / 17);
}

private void button1_Click(object sender, EventArgs e)
{
    String donationBeforeFees;
    Double aFees;
    String totalDonationRaised;

    donationBeforeFees = donationBox.Text;
    donationBFees = System.Convert.ToDouble(donationBeforeFees);

    double afterFees = donationBFees;
    operatingCost(ref afterFees);
    afterFeesBox.Text = afterFees;
}

你应该告诉你的教授,这并不是一个很好的使用 byref 参数。如果该功能扣除运营成本可能更有意义:

void deductOperatingCost(ref double afterFeesParam)
{
    afterFeesParam = afterFeesParam - (afterFeesParam / 17);
}

这样你给它一个值,它会稍微变小。

【讨论】:

  • 非常感谢罗宾。这对我帮助很大。我在代码中保留了 afterFeesParam,以免与其他变量混淆。我也按照其他人的建议改为十进制,我还注意到我计算的百分比错误,所以我修复了这个问题。感谢您的所有建议和帮助。
【解决方案3】:

我将方法从 onClick 中移出,我更改了用于查找捐赠百分比(用户输入)的计算。我还将输出格式化为仅显示小数点后两位并显示美元符号。我仍然需要创建错误处理程序来验证用户输入,但这应该不是问题。我在通过 ref 传递时遇到了问题,但我对它的工作原理有了更好的理解。谢谢大家的帮助!

private decimal donationBFees = 0;

    void deductOperatingCost(ref decimal afterFeesParam)
    {
        afterFeesParam = afterFeesParam - (afterFeesParam  / 100 * 17);
    }


    private void Button_Click(object sender, RoutedEventArgs e)
    {
        String donationBeforeFees;
        Decimal aFees;
        String totalDonationRaised;

        donationBeforeFees = donationBox.Text;
        donationBFees = System.Convert.ToDecimal(donationBeforeFees);


        decimal afterFees = donationBFees;
        deductOperatingCost(ref afterFees);
        afterFeesBox.Text = afterFees.ToString("$###, ##0.00");

    }

【讨论】:

  • 将donationBFees 作为类字段引入并不是最好的主意,因为它会导致不必要的副作用。本地声明就足够了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 2020-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多