C# 获取解析失败的实际值
免责声明这个问题是关于,如果和如何我们可以使用C# 获取解析失败的实际值,c#,try-catch,C#,Try Catch,免责声明这个问题是关于,如果和如何我们可以使用解析方法异常,来查找转换失败的参数/变量。争论这是最好的还是正确的方法是而不是TryParse或后续if语句。然而,每一种备选方案或解决办法都值得赞赏 我有下面的C代码块# 这里的intb1=int.Parse(b)行将失败,catch块将捕获异常 是否可以通过编程方式检查异常信息,找到导致错误的实际值(字符串b的值,而不是变量的名称)。例如,我想得到如下结果: 无法分析“b” 不可靠-在FormatException中没有任何内容可以为您做到这一点
解析
方法异常,来查找转换失败的参数/变量。争论这是最好的还是正确的方法是而不是TryParse
或后续if
语句。然而,每一种备选方案或解决办法都值得赞赏
我有下面的C代码块#
这里的intb1=int.Parse(b)代码>行将失败,catch块将捕获异常
是否可以通过编程方式检查异常
信息,找到导致错误的实际值(字符串b的值
,而不是变量的名称)。例如,我想得到如下结果:
无法分析“b”
不可靠-在
FormatException
中没有任何内容可以为您做到这一点。解析消息是非常脆弱的-它可以在不同版本的.NET中更改,并且将被本地化
一个选项是编写自己的Parse
方法,该方法可与int.Parse
互操作,但会抛出FormatException
的子类。例如:
public class ParseException : FormatException
{
public string OriginalValue { get; }
public ParseException(string message, string originalValue)
: base(message)
{
OriginalValue = originalValue;
}
}
public class ExtendedParsing
{
public int ParseInt32(string value)
{
int result;
if (int.TryParse(value, out result))
{
return result;
}
throw new ParseException($"Unable to parse \"{value}\"", value);
}
}
然后您可以将其用作:
try
{
int a1 = ExtendedParsing.ParseInt32(a);
int b1 = ExtendedParsing.ParseInt32(b);
int c1 = ExtendedParsing.ParseInt32(c);
}
catch (ParseException e)
{
Console.WriteLine($"Value that I failed to parse: {e.OriginalValue}");
}
改用TryParse(您不需要整个try-catch),例如:
int a1=0;
if(!int.TryParse(a, out a1))
{
//do something here
}
int b1=0;
if(!int.TryParse(b, out b1))
{
//do something here
}
int c1=0;
if(!int.TryParse(c, out c1))
{
//do something here
}
这个简单的图案怎么样
string a = "1";
string b = "b";
string c = "3";
int aInt, bInt, cInt;
if (!int.TryParse(a, out aInt))
{
//report e.g.
Console.WriteLine($"Could not parse {nameof(a)}");
}
if (!int.TryParse(b, out bInt))
{
//report e.g.
Console.WriteLine($"Could not parse {nameof(b)}");
}
if (!int.TryParse(c, out cInt))
{
//report e.g.
Console.WriteLine($"Could not parse {nameof(c)}");
}
我们使用这种模式(主要是为了避免本地化消息和中性日志消息的切换/大小写,为了简单起见,这里没有显示,否则@JonSkeet的解决方案创建自定义异常并调用包装器方法是正确的方法): 其思想是在做某事之前设置原因(可以选择在做某事之后清除),如果失败,则执行-向用户显示原因
有些东西可以是任何一段代码,因此我不想通过建议
TryParse
来改进解析,我会用TryParse
来解决它-这种方法有什么问题?TryParse
不是一种“变通方法”但唯一可靠的方法是另一种选择是将其实际拆分为多个try catch
块,以便您确切知道失败的原因,但是我真的不认为在这里避免TryParse
有什么意义。我想他想知道在他的Exception e
中是否有关于变量名的信息-我认为这不是你可以编写自己的解析方法(wrapper-around int.parse)这将提供有关异常中失败值的信息。这将是我首选的解决方案。在这种情况下没有必要进行异常处理。@DanWilson我也这么想:D Jon正在用大锤敲开一颗坚果。回答得很好,但正如我所说的,我知道如何“用这种方式”来做。我只是在寻找替代方案,如果我能通过Parse
和Exceptions
@Athafoud实现这一点:是的,其他答案证明了存在替代方案,但是。如果你在解析一个字符串,那么我认为假设它可能不是一个整数是公平的。异常处理是过火了,IMHO。答案很好,但正如我所说的,我知道如何“以这种方式”处理。我只是在寻找替代方案,如果我能通过Parse
和Exceptions
string a = "1";
string b = "b";
string c = "3";
int aInt, bInt, cInt;
if (!int.TryParse(a, out aInt))
{
//report e.g.
Console.WriteLine($"Could not parse {nameof(a)}");
}
if (!int.TryParse(b, out bInt))
{
//report e.g.
Console.WriteLine($"Could not parse {nameof(b)}");
}
if (!int.TryParse(c, out cInt))
{
//report e.g.
Console.WriteLine($"Could not parse {nameof(c)}");
}
string problem = null;
try
{
problem = "Can't parse a";
var a1 = int.Parse(a);
problem = "Can't parse b";
var b1 = int.Parse(b);
problem = "Can't parse c";
var c1 = int.Parse(c);
problem = "Can't do something";
... // something
}
catch(Exception e)
{
Logger.Add(e);
UserMessage(problem);
}