我想在catch
块中使用一个对象,这会在try
块中产生异常。我将一些字符串解析为int
并且需要在不可能的情况下捕获异常,并查看错误的对象以及在哪一行。这可能与否?
一些代码示例。感谢。
static void Main(string[] args)
{
var result = Parse(new List<string>() { "3;5;7", "qwe;3;70" });
}
public static List<int[]> Parse(List<string> list)
{
try
{
return list.Select(str => str.Split(';'))
.Select(str => Tuple.Create(int.Parse(str[0]), int.Parse(str[1]), int.Parse(str[2])))
/// something happening
.ToList();
}
catch
{
//here in braces I want to know, which element was wrong
//"qwe" and whole line "qwe;3;70"
throw new FormatException($"Wrong line [{}]");
}
}
答案 0 :(得分:1)
声明try/catch
块之外的行和值项计数器,并在LINQ表达式主体中增加它们:
public static List<int[]> Parse(List<string> list)
{
int line = 0;
int item = 0;
try
{
return list
.Select(str => {
line++;
item = 0;
return str
.Split(';')
.Select(i => { item++; return int.Parse(i); })
.ToArray();
})
.ToList();
}
catch
{
throw new FormatException($"Wrong line [{line}]; item [{item}]");
}
}
答案 1 :(得分:1)
您需要引用导致异常的对象。但是,由于实例仅存在于try-block的范围内,因此您无法再访问它(尝试捕获并不共享相同的范围,因此无法访问相同的变量),除非您声明引用到try-bloc之外的那个实例
正如评论中已经提到的,您应该使用正常的foreach
- 循环来访问当前行:
public static List<int[]> Parse(List<string> list)
{
var result = new List<int[]>();
foreach(var str in list)
{
try
{
var values = str.Split(';');
result.Add(Tuple.Create(
int.Parse(values[0]),
int.Parse(values[1]),
int.Parse(values[2]))
);
}
catch
{
//here in braces I want to know, which element was wrong
throw new FormatException($"Wrong line " + str");
}
}
return result;
}
但是,您可以通过使用TryParse
来避免所有这些异常,如果解析失败则返回false。所以这归结为这样的事情:
var values = str.Split(';');
int v0, v1, v2;
if(int.TryParse(values[0], out v0 &&
int.TryParse(values[1], out v1 &&
int.TryParse(values[2], out v2 &&))
result.Add(Tuple.Create(v0, v1, v2));
else
throw new FormatException($"Wrong line " + str");
答案 2 :(得分:1)
我建议手动循环,分割数据,检查是否有足够的元素,然后在数字上使用TryParse。我知道这与使用Linq有所不同,但这是通过错误检查执行此操作的更好方法:
public static List<int[]> Parse(List<string> list)
{
if (list == null)
{
throw new ArgumentNullException("list");
// you can use nameof(list) instead of "list" in newer versions of C#
}
List<int[]> result = new List<int[]>();
// Loop through the entries
for (int i = 0; i < list.Count; ++i)
{
// Be safe and check we don't have a null value
// I'm just skipping the 'bad' entries for now but
// you can throw an error, etc.
if (list[i] == null)
{
// do something about this? (an exception of your choosing, etc.)
continue;
}
// split the entry
string[] entryData = list[i].Split(';');
// check we have 3 items
if (entryData.Length != 3)
{
// do something about this?
continue;
}
// try to parse each item in turn
int a;
int b;
int c;
if (!int.TryParse(entryData[0], out a))
{
// do something about this?
continue;
}
if (!int.TryParse(entryData[1], out b))
{
// do something about this?
continue;
}
if (!int.TryParse(entryData[2], out c))
{
// do something about this?
continue;
}
// add to the results list
result.Add(new int[] { a, b, c });
}
// return the result
return result;
}
答案 3 :(得分:0)
范围是范围。您在try
区块内定义但未明确传递的任何内容都无法在catch
区块中显示。
如果您需要此信息,则必须在列表上手动迭代并尝试单独捕获每次尝试...
答案 4 :(得分:0)
您的代码存在太多问题,您假设参数list
不为空并且包含可以在3个字符串中拆分的项目,并且每个字符串都可以安全地解析为{{ 1}}。
如果您没有上述所有保证,请检查所有内容:
int
答案 5 :(得分:0)
我认为你这里的方法错了。是的,使用Tuple + Linq将是获得结果的最懒惰的方法,但是你不能生成自定义错误。
以下是一个如何实现相似内容的示例:
static void Main(string[] args)
{
var result = Parse(new List<string>() { "3;5;7", "qwe;3;70" });
}
public static List<Tuple<int, int, int>> Parse(List<string> list)
{
List<Tuple<int, int, int>> result = new List<Tuple<int, int, int>>();
int line = 0;
int errorCol = 0;
try
{
for (line = 0; line < list.Count; line++)
{
string[] curentLine = list[line].Split(';');
int result0, result1, result2;
errorCol = 1;
if (curentLine.Length > 0 && int.TryParse(curentLine[0], out result0))
errorCol = 2;
else
throw new Exception();
if (curentLine.Length > 1 && int.TryParse(curentLine[1], out result1))
errorCol = 3;
else
throw new Exception();
if (curentLine.Length > 2 && int.TryParse(curentLine[2], out result2))
result.Add(new Tuple<int, int, int>(result0, result1, result2));
else
throw new Exception();
}
return result;
}
catch
{
//here in braces I want to know, which element was wrong
throw new FormatException("Wrong line " + line + " col" + errorCol);
}
}
PS:行和列从0开始。