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<TResult>以这种方式使用委托:

我写了以下方法:

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"));

其他解决方案?

4

4 回答 4

0

似乎您并不关心哪个解析失败,而只需要一个默认值就可以了?如果是这样,首先将您的 vars 初始化为默认值,然后在一个 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);

但是有一个警告:几何没有实现 TryParse...(假设您使用System.Windows.Media.Geometry

这让我明白了这一点:

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

无论哪种方式:验证用户输入都是有代价的。

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

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

于 2013-11-03T11:31:35.620 回答
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'
}
于 2013-11-03T10:43:57.450 回答
-1

TryParse 更可取,因为您在抛出和捕获异常时没有性能损失。

上面代码中还有一个不准确之处——解析的“0”和默认(T)之间没有区别。

代码比你的快

public static class StringExt
    {
        public static double ParseDouble(this string value)
        {
            double result;
            Double.TryParse(value, out result);
            return result;
        }

    }
于 2013-11-03T10:37:06.443 回答
-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,也没有解释在发生异常时必须做什么。Hance 我认为他不想做任何事情,以防出现异常。

于 2013-11-03T10:43:07.133 回答