C# 使用(尝试)分析将空字符串加倍

C# 使用(尝试)分析将空字符串加倍,c#,parsing,double,tryparse,C#,Parsing,Double,Tryparse,我有一个1.1版本的构建系统,使用解析转换值(现在是3.5) 抛出FormatException(我预期为0.0) 如果我用2.0重写的话+ string myString = String.Empty; double myValue; if (double.TryParse(myString, out myValue)) //do something 我得到了想要的0.0,但不幸的是,我失去了获得有意义的错误消息的可能性(在else树中) 为什么给我一个解析错误和TryParse我的

我有一个1.1版本的构建系统,使用解析转换值(现在是3.5)

抛出FormatException(我预期为0.0)

如果我用2.0重写的话+

string myString = String.Empty;
double myValue;
if (double.TryParse(myString, out myValue))
    //do something
我得到了想要的0.0,但不幸的是,我失去了获得有意义的错误消息的可能性(在else树中)

为什么给我一个解析错误和TryParse我的期望值? 有没有办法从TryParse中获取错误消息(时间不是问题)

我不想这样做:

  • 使用if…then避免错误

    myValue = myString.Length == 0 ? 0.0 : double.Parse(myString);
    
  • 如果发生错误,则进行两次调用

    if (!double.TryParse(myString, out myValue))
        myValue = double.Parse(myString);
    
为什么给我一个解析错误和TryParse我的期望值

因为这就是界面的设计方式<如果输入的格式无效,code>TryParse不会引发异常。相反,它返回
false

有没有办法从TryParse中获取错误消息(时间不是问题)

不,但您可以自己生成错误消息

if (double.TryParse(myString, out myValue))
{
    //do something
}
else
{
    throw new FooException("Problem!");
}

但是,如果您想在出现错误时抛出异常,只需使用
Parse

就可以了。不,不可能获得准确的错误消息。您只想知道是否可以转换为double,以及结果(如果可以)。转换失败的确切原因是隐藏的。

Parse
如果无法解析字符串,则抛出异常,并且
TryParse
返回一个
bool
。您可以处理此bool(如果解析成功,则为true,否则为false),以显示要显示的成功/错误消息


由于
myValue
是一个
out
参数,因此必须由该方法设置,因此,如果无法解析字符串,TryParse将其设置为0.0,这就是为什么在使用TryParse方法时会得到该数字。

TryParse允许您在不引发异常的情况下进行转换,如果成功,则返回true。你采取的行动取决于你自己

if (!double.TryParse(myString, out myValue))
{
//throw exception here
}

当您不确定输入是否始终是数字时,此功能非常有用

TryParse
以如下方式实现:

try
{
    Parse(...);
    return true;
}
catch
{
    return false;
}
所以你可以用同样的方法:

try
{
    double.Parse(str, out dbl);
}
catch (Exception ex)
{
    // Do something with ex.Message
    dbl = 0.0;
}

// Continue with dbl.

忘记
double.TryParse
,因为它不会告诉您(设计上)解析失败的原因。按老办法做:

string myString = String.Empty;
double myValue = 0.0;

try
{
    myValue = double.Parse(myString);
}
catch (FormatException)
{
    // Now you have a meaningful story here!
}

必须设置Out参数,因此如果TryParse失败,它将在返回之前将输出初始化为默认值,但是您将在“else”循环中。。。意味着它失败了

尝试运行下面的代码,这将显示TryParse实际上覆盖了该值,但表明解析失败

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                ParseAndOutput("");
                ParseAndOutput("1.0");
                ParseAndOutput("ABC");
            }

            private static void ParseAndOutput(string input)
            {
                double value = -1;
                if (double.TryParse(input, out value))
                {
                    Console.WriteLine("Parse succeeded for '"+input+"', try parse changed to: " + value);
                }
                else
                {
                    Console.WriteLine("Parse failed for '" + input + "', try parse changed to:  " + value);
                }
            }
        }
    }

因此,Parse和TryParse在字符串上都失败。Empty,它们只是以不同的方式报告失败,这就是TryParse的全部意义,它从来不会引发异常…

为什么“输入字符串格式不正确”,“有意义的错误消息”?有什么问题?空字符串不是有效的双精度数字。您希望错误消息中有多少详细信息?我很确定您没有正确描述内部行为,并且当您使用
TryParse
数字时,没有内部try/catch。啊,您是对的,bool返回false,虽然它是真的。实现这一点的一种方法是
内部静态bool解析(字符串s、NumberStyles样式、IFormatProvider提供程序、bool tryParse、out double result、out Exception exc)
并在
Parse()
tryParse()
中使用它(Mono中就是这样实现的)。创建异常对象不是问题,但是抛出/捕获它会很昂贵。这将是一个非常低效的实现,抛出和捕获异常会很昂贵。更可能是相反。当然,我同意,你不应该在逻辑上使用异常,而且实现很糟糕。我不会使用它但当我说出这个答案时,我指的是他的评论“时间不是问题”。这只是一个答案——如果它有意义或没有意义,这是询问者的决定。;)我怎么知道发生了哪种类型的异常?@UNeverNo你到底是什么意思?除了假返回值提供的“这不能转换为双精度”之外,您还需要知道哪些其他信息?FormatException。您甚至不需要再知道'cos
false
表示转换没有成功。只要告诉你的用户界面这个值不是supported@UNeverNo:没有发生异常,即使它发生在内部,TryParse也应该将该异常“消化”为布尔值“false”。“尝试”方法的要点是,他们应该完成自己的工作,而不允许“可消化”的异常进入我们“粗野流动”的血液。你也是对的。我以为TryParse为String.Empty返回了true。
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                ParseAndOutput("");
                ParseAndOutput("1.0");
                ParseAndOutput("ABC");
            }

            private static void ParseAndOutput(string input)
            {
                double value = -1;
                if (double.TryParse(input, out value))
                {
                    Console.WriteLine("Parse succeeded for '"+input+"', try parse changed to: " + value);
                }
                else
                {
                    Console.WriteLine("Parse failed for '" + input + "', try parse changed to:  " + value);
                }
            }
        }
    }