C#中属性的ref替代项

本文关键字:ref 属性 | 更新日期: 2023-09-27 18:19:47

我有一个函数,它从TextBox中读取Text,然后尝试将其解析为数字。如果可能的话,它将存储解析后的数据。如果不可能,则不触摸数据,而是将TextBox.Text设置为变量的字符串表示。由于我需要它来处理各种文本框和底层变量,我的函数如下所示:

public bool ValidateAndParseTextBox(TextBox textBox, ref double storage)
    {
        try
        {
            storage = double.Parse(textBox.Text);
            return true;
        }
        catch (FormatException)
        {
            textBox.Text = storage.ToString();
            return false;
        }
    }

int 也是如此

现在,我将底层数据移动到一个单独的对象中,因此我想使用属性,而不仅仅是公开变量。然而,对于这些,我不能使用ref语句。

如果我不需要布尔return值,我可以像这个一样做

public double ValidateAndParseTextBox(TextBox textBox, double Value)
    {
        double ret;
        if (!double.TryParse(textBox.Text, ret))
            return Value;
        return ret;
    }

但不知何故,我没能找到布尔值的解决方案。有什么想法吗?如果我能以某种方式将属性setter作为委托发送给一个函数或类似的东西,那将是一件好事。

谢谢,-m-

C#中属性的ref替代项

对我来说,这个函数似乎做得太多了。有一个纯函数,它只接受文本框,验证它并返回一个bool。

public bool IsTextboxValid(TextBox textBox)
{
    double dummy;
    return double.TryParse(textbox.Text, out dummy);
}

根据此函数的结果,调用方可以决定是否设置属性。


另一种方法是返回一个可以为null的double,它指示解析是否成功,以及double值是什么(如果有的话)

public double? ParseTextbox(TextBox textBox)
{
    double ret;
    if(double.TryParse(textbox.Text, out ret))
        return ret;
    else
        return null;
}

从调用者的角度来看,它可以检查返回值.HasValue,在这种情况下,它可以更新存储,否则,它会用存储值更新文本框。


你的问题的字面答案是,是的,你可以传递一个将属性设置为参数的委托:

public bool ValidateTextbox(TextBox textBox, Action<double> setValue)
{
    bool parseSucceeds;
    double d;
    if (parseSucceeds = double.TryParse(textBox.Text, out d))
        setValue(d);
    return parseSucceeds;
}

您可以使用d => whatever.Path.To.The.Property = d作为参数来调用它。不过我不建议这样做。

如果你想让一个方法有多个返回值,你基本上有两个选项:

  1. 使用描述这两个值的结构
  2. 使用refout参数

在您的情况下,您可以简单地返回一个null,然后就可以了。使用结构通常是一种更干净的设计,因为您不依赖于调用语言(如果它与C#不同)知道ref和out参数,而后一种选项的速度要快一些。

//edit:哦,您可能想知道double值,而不考虑解析是否成功。因此,最好定义自己的结构。