Console.Write 会失败吗?

5
我正在测试我的run()函数,以确保方法结束时拥有所有正确的内容。我从我们的数据库中填充了4个字段,两个字符串和两个IEnumerable(string)。 我的想法是为从数据库中提取的所有人打印出这些内容。
当我只打印字符串字段时,一切都正常工作。 但是,当我尝试添加Enumerable时,根本没有打印任何内容。我还打印了一个计数器,以便知道程序仍在运行和工作。由于空间或其他原因,Console是否决定根本不打印任何东西?
以下是执行此操作的代码:
int i = 0;
foreach (Contact contact in Contact.LoadWithPredicate(getAll))
        {
                -------other code to populate fields---------

                i ++;
                Console.WriteLine(i);
                //Turn the Enumerables into strings for printing
                string firstEnumAsString = String.Join(", ", firstEnumerable.ToArray());
                string secondEnumAsString = String.Join(", ", secondEnumerable.ToArray());

                Console.WriteLine("Email: " + firstString+ ", correspondance: " + secondString+ ", PAM addresses: " + firstEnumAsString+ ", famousPeople: " + secondEnumAsString);
}

当我运行上述代码时,输出结果如下:
1

2

Email: foo@bar.com, correspondance: John, PAM addresses: bar@foo.com, famousPeople: foo, bar, foo

3

4

etc

问题是,整个列表中(约425人)只有两个人出现了,其余的行都只是数字。我至少应该得到"Email"和", correspondence"这两个字符串吧?似乎控制台只是决定什么也不做。我知道代码必须到达这里,因为在调用Console.WriteLine()之前它打印了整数i。
另一方面,每当我只要求打印这两个字符串字段时,控制台就会显示所有425个用户的两个字段,紧接着它们相应的整数。有人知道这里发生了什么吗?谢谢。

3
在C#中,字符串连接被规定为将null视为空字符串,所以除非框架存在缺陷,否则问题不可能出在这里。来源:http://msdn.microsoft.com/en-us/library/ms228504.aspx - user743382
2
据我所知,+ 无论如何都会调用 String.Concat 方法(并将 null 转换为 String.Empty)。 - Chris
1
@ScottChamberlain - 没有区别(只是符号表示不同)。 - H H
1
@AlexChumbley - 这不是 Console.Write()。你的数据中可能有一些控制字符。 - H H
2
@AlexChumbley:另外,这是你程序中的确切代码吗?你不会碰巧有一个try/catch捕获了异常,对吧? - Chris Sinclair
显示剩余17条评论
2个回答

4
根据您的评论,我认为您的 firstEnumerablesecondEnumerable 对象其中之一是null,但由于您没有发布如何获取这些对象的信息,我不能评论它们为什么是null或如何解决它。
它们可以包含null条目,甚至完全为空,但本身不能为null,否则在调用.ToArray()时会抛出一个ArgumentNullException,这与您看到的“值不能为空”异常消息相对应。
您迭代循环内使用了try/catch块来捕获(和记录?)异常,这在您的代码示例中未被发布,所以它不会彻底崩溃。
我猜测您的实际代码类似于此:
foreach (Contact contact in Contact.LoadWithPredicate(getAll))
{
    try
    {
        ...

        object[] firstEnumerable = null;
        object[] secondEnumerable = null;

        //some logic gates here which under some circumstances do not 
        //assign a valid instance to firstEnumerable or secondEnumerable

        ...
        Console.WriteLine(i); //this prints every time

        //Turn the Enumerables into strings for printing
        string firstEnumAsString = String.Join(", ", firstEnumerable.ToArray()); //exception here
        string secondEnumAsString = String.Join(", ", secondEnumerable.ToArray()); //or exception here

        Console.WriteLine("Email: " + firstString+ ", correspondance: " + secondString+ ", PAM addresses: " + firstEnumAsString+ ", famousPeople: " + secondEnumAsString);
        ...
    }
    catch
    {
        //maybe some logging? maybe not?
    }
}

这将每次打印出 i 值。但是当它尝试创建 firstEnumAsString 或 secondEnumAsString 时,它会抛出异常,从而永远不会触发您的第二个 Console.WriteLine(“电子邮件:”+ ...); ,从而产生您看到的输出。问题不在于 Console.WriteLine 失败,而在于您根本没有首先调用它。

2
如果值为 null,则仅将行终止符写入标准输出流。有关行终止符的更多信息,请参阅 WriteLine() 方法的“备注”部分。 此外,如果您尝试将要写入控制台的某个值抛出异常(例如以下代码中所示):
    private static string SomeVal { get { throw new Exception(); } }

    Console.WriteLine("Foo");
    Console.WriteLine("This throws an exception: " + SomeVal);

“这会抛出异常:” 这句话也不会被写入控制台; 整个字符串都被视为 null。在我的看法中,这就是你的代码实际上正在发生的事情;你正在尝试将其中一个值写入控制台时,它抛出了异常,并且在某个地方被静默处理。你是否在一个抑制性的 try/catch 子句中运行此代码?
您可以通过在 Console.WriteLine 或结尾的 } 上设置断点并检查 firstStringsecondString 的值是否为 null 来轻松确定是否是这种情况。您还可以判断您正在尝试写入的值之一是否引发了异常。
此外,您应该考虑使用 string.Format(string format, params object[] args) 而不是使用 + 进行字符串连接。这样调试代码也会更容易。

谢谢@Aevitas,我很感激。有没有办法让控制台在这些字段中写出null而不是使整个字符串为null? - Alex Chumbley
2
@AlexChumbley 使用格式 firstString ?? "NULL" ,这被称为 [null-coalescing 操作符] (http://msdn.microsoft.com/en-us/library/ms173224.aspx)。如果变量为 null,它将使用 ?? 后面的内容替换。 - Scott Chamberlain
问题在于,如果我的假设是正确的并且这些值确实引发异常,那么它们的值不是null - 实际上它们根本没有值。当检查null时,它们将在执行期间被忽略。 - aevitas

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