在try-catch块中如何正确地放置语句?

5

我需要依次执行大量语句,并且当单个语句抛出异常时,需要程序流继续执行下一个语句,例如

double a = Double.Parse("2.5");
double b = Double.Parse("ADFBBG");
Geometry g = Geometry.Parse("M150,0L75,200 225,200z");

所有语句都必须被执行,因此我需要一种级联的try-catch块:

double a, b;
Geometry g;

try
{
   a = Double.Parse("2.5");
}
catch
{}

try
{
   b = Double.Parse("ADFBBG");
}
catch
{}

try
{
   g = Geometry.Parse("M150,0L75,200 225,200z");
}
catch
{}

显然这不是我编写程序的最优雅方式。是否有更好的方法(更优雅,而且不会显著降低性能)?
我尝试使用Func委托来实现,如下所示:
我编写了以下方法:
T Try<T>(Func<T> func)
{
    try
    {
        return func();
    }
    catch
    {
        return default(T);
    }
}

所以我可以像这样使用它:
double x = Try(() => Double.Parse("77"));
Geometry g = Try(() => Geometry.Parse("M150,0L75,200 225,200z"));

其他解决方案?

8
希望你的问题不是基于将字符串解析为双精度浮点数,因为你可以使用TryParse而不是Parse来避免异常抛出的问题。请注意,这样做并不会改变原有功能。 - Steve
1
如果“转换失败”(即语句抛出异常),则必须使用其默认值初始化变量。@O.R.Mapper - gliderkite
8
你需要一个更好的例子,否则你只会得到TryParse的答案。 :-) - John Saunders
6
你的尝试函数是一个很好的解决方案。继续使用它。 - David Arno
2
尝试功能加1。我想那是最好的解决方案,选择它吧。 - Rohit Vats
显示剩余6条评论
4个回答

0

使用 Double.TryParse

它返回一个值,指示转换是否成功。因此,您可以按以下方式使用它:

double converted;
bool success = Double.TryParse(value, out converted);

if (success)
{
    // Do whatever you want
    // The converted value is in the variable 'covnerted'
}

0

看起来你并不关心哪个解析失败了,只需要在失败的情况下有一个默认值?如果是这样,请先将变量初始化为默认值,然后在单个 try-catch 中进行解析:

double a=0.0, b=0.0;
Geometry g = new Geometry();

try
{
   a = Double.Parse("2.5");
   b = Double.Parse("ADFBBG");
   g = Geometry.Parse("M150,0L75,200 225,200z");
}
catch
{
    //At least mark that conversion was not succesful
}

当抛出异常时,try-catch才会对性能产生影响。如果一切正常,try-catch的影响很小。请参见问题。 比您发布的代码更优雅,但至少更简洁。

使用TryParse的替代方案

double a=0.0, b=0.0;
Geometry g = new Geometry();

Double.TryParse("2.5", out a);
Double.TryParse("ADFBBG", out b);
Geometry.TryParse("M150,0L75,200 225,200z", out g);

但是有一个注意点:Geometry没有TryParse实现...(假设您使用System.Windows.Media.Geometry)

这就带我来到了重点:

  • 使用您的Try<>函数,不会减少开销,但很干净
  • 首先验证字符串。虽然可以消除尝试的开销,但会在解析时引入运行时开销。

无论哪种方式:验证用户输入都有其成本。

回答主要问题:如何正确地将语句放置在try-catch块中? 如果您不关心哪个语句失败:1个try-catch。

但是:如果第一条语句失败,则其他语句将不会被执行。 但是,您的系统已经处于失败/损坏状态。 进一步处理是否会产生正确的结果? (我怀疑)


-1
尝试解析(TryParse)更可取,因为在抛出和捕获异常时不会有性能惩罚。
还有一个关于上述代码的不准确之处- 解析“0”和default(T)之间没有区别。
代码比你的更快。
public static class StringExt
    {
        public static double ParseDouble(this string value)
        {
            double result;
            Double.TryParse(value, out result);
            return result;
        }

    }

-1

我几天前已经回答了类似的问题。如果您有一组字符串值,您可以利用扩展方法的威力来完成此操作。

static public IEnumerable<double> ConvertToDouble(this IEnumerable<string> source)
{
    double x = 0;
    var result = source.Where(str => Double.TryParse(str, out x))
                        .Select (str => x);

    return result;      
}

所以将所有内容放入集合中,然后使用.AsEnumerable()ConvertToDouble()扩展方法。无法解析的所有内容都将被忽略,不会引发异常,并且结果的类型为IEnumerable<Double>

原始回答:在C#中将List<string>转换为List<int>

/编辑:那位投票者能否解释一下?OP并没有说明他想要使用try catch,并且也没有解释在出现异常时应该做什么。因此我认为他并不想在出现异常时执行任何操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接