在foreach语句中处理强制转换异常

JMK*_*JMK 3 c# error-handling enumeration

好吧,假设我在C#.Net中有一个对象数组,如下所示:

object[] myObjects = new object[9];
myObjects[0] = "Foo";
myObjects[1] = 3;
myObjects[2] = 2.75;
myObjects[3] = "Bar";
myObjects[4] = 675;
myObjects[5] = "FooBar";
myObjects[6] = 12;
myObjects[7] = 11;
myObjects[8] = "FooBarFooBar";
Run Code Online (Sandbox Code Playgroud)

我希望,在foreach块中,枚举此数组并使用StreamWriter将每个字符串写入文本文档,如下所示:

StreamWriter sw = new StreamWriter(@"C:\z\foobar.txt");

foreach(string myObject in myObjects)
{
    sw.WriteLine(myObject);
}

sw.Flush();
sw.Close();
Run Code Online (Sandbox Code Playgroud)

我的问题是,每当我试着投了integersdoublesString,一个异常将被抛出.

如果我try/catch在我的foreach语句周围放置一个块,那么在第二次迭代中抛出的异常将触发捕获异常,并且不会将任何内容写入我的文本文档.

将try/catch放在foreach中是没有意义的,因为异常发生在转换上.

我想使用foreach循环(让我们假设for循环不存在,并且我们不能使用索引或ToString())枚举对象数组,将每个对象转换为字符串并使用它们将它们写入文本文档StreamWriter.如果演员工作,快乐的日子.如果没有,我想捕获抛出的异常并继续枚举剩余的对象.

谢谢

编辑:在有人说之前,这不是功课!我正在努力解决一个现实世界的问题.

Mic*_*Liu 6

因为你期望一个异构的集合,所以最好避免抛出InvalidCastException第一个位置.阅读Eric Lippert优秀的Vexing例外文章中的"愚蠢的例外" .

选项1:使用LINQ OfType<TResult>()扩展方法仅选择指定类型的元素:

// using System.Linq;

foreach(string myObject in myObjects.OfType<string>())
{
    sw.WriteLine(myObject);
}
Run Code Online (Sandbox Code Playgroud)

选项2:自己进行类型检查:

foreach(object myObject in myObjects)
{
    string s = myObject as string;
    if (s != null)
        sw.WriteLine(s);
}
Run Code Online (Sandbox Code Playgroud)

此选项很容易扩展以处理多种类型.

更新:

好的,但是如果在一些古怪的情况下,仍然会在这条线上抛出异常会发生什么.有没有办法处理异常,然后继续我的枚举?

以下是foreach在行上抛出异常的其他方法,其中没有一个可以合理处理:

  • myObjects.GetEnumerator()抛出一个例外.在这种情况下,枚举根本无法启动.
  • IEnumerator<string>.MoveNext()抛出一个例外.在这种情况下,枚举器可能已损坏,枚举无法继续.
  • 发生了一些其他类型的致命异常:OutOfMemoryException,StackOverflowException等等.在这种情况下,您应该让进程死亡.