C# 正在将文本文件读入字符串数组-为什么会得到意外的输出?

C# 正在将文本文件读入字符串数组-为什么会得到意外的输出?,c#,arrays,text-files,C#,Arrays,Text Files,尝试创建一个简单的刽子手游戏,其中读取一个外部文本(称为words.txt),并将其中的字符串导入到一个名为WordsArray的字符串数组中 程序编译得很好,但是,在显示填充数组的内容之前,它要求我输入两次文件名(请参阅下面的foreach循环) 是否有人能在显示之前确定为什么它两次询问我文件名 (更一般地说,我的重构是否适合这个简单的应用程序?) 这是因为您调用了LoadWords()两次 你应该写: string[] WordsArray= LoadWords(); if (WordsAr

尝试创建一个简单的刽子手游戏,其中读取一个外部文本(称为words.txt),并将其中的字符串导入到一个名为WordsArray的字符串数组中

程序编译得很好,但是,在显示填充数组的内容之前,它要求我输入两次文件名(请参阅下面的foreach循环)

是否有人能在显示之前确定为什么它两次询问我文件名

(更一般地说,我的重构是否适合这个简单的应用程序?)


这是因为您调用了LoadWords()两次

你应该写:

string[] WordsArray= LoadWords();
if (WordsArray != null)
{
  Console.WriteLine("File Loaded...\n\n");
  DisplayWordsArray(WordsArray);
  ...

正如一些评论和Jesper的回答中提到的,这种双重性是由于调用函数
LoadWords()
两次造成的。这是导致bug的常见原因,往往是由于需要编写尽可能少的代码行(通过直接使用函数消除变量声明和初始化)

除此之外,当错误可以以其他方式处理时,故意触发异常是不谨慎的。请参阅中的以下代码段:

对于可能发生但可能触发异常的条件,考虑以避免异常的方式处理它们。

由于存在用于检查文件是否存在的方法
File.Exists()
,因此使用该方法而不是预测异常是合适的

START\u EDIT:由于文件可以被外部进程删除、锁定或以其他方式更改,因此使用@RufusL提到的
try…catch
块是谨慎的(也可以查看Eric Lippert的帖子)。我有罪结束编辑


最后,重构很好:几乎总是最好让一个方法处理一件事,并且处理得很好。

将逻辑更改为只回答一次问题,并处理已知的文件丢失故障。如果发生异常,请退出:

static string[] LoadWords()
{
    string[] WordsArray = null; 
    Console.WriteLine("Please enter the name of a file:");

    do
    {
        try
        {  
            string filename = Console.ReadLine();

            if (File.Exists(filename))
                WordsArray = File.ReadAllLines(filename);
            else
                Console.WriteLine($"{Environment.NewLine} File does not exist, try again: ");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"{Environment.NewLine} Unknown exception, exiting. {ex.Message}");
            return null;
        }
    }
     while (WordsArray == null)

    return WordsArray;
}

调用
File.Exists(…)
以确定文件是否可行,而不是在文件不可行时捕获错误。它请求文件名两次,因为您正在调用
LoadWords()
twice。我知道,当其结果与null比较时,对LoadWords()的调用会出现在选择语句中。然而,在这种情况下,我认为返回的结果只会被调用…而不是其中的完整实现。每次调用方法时,都会执行方法代码。如果您想多次使用返回值,请将其保存到一个变量。@ΩmegaMan根据Eric Lippert的说法,OP的设计是正确的-请查看本文的“外部异常”部分:致命、愚蠢、恼怒、外部……哈哈!这是一个有趣的阅读@RufusL。我会修改我的答案,以免一些粗心的人掉入陷阱。我可以再补充一个问题吗?我总是必须使用“new”关键字初始化数组。为什么在上面粘贴的解决方案中,没有使用“new”关键字,因为它正在“初始化”单词sarray?(除了使用方法返回值这一明显事实之外)@Tiny-当您调用
File.ReadAllLines
时,文件将被读入
列表中。然后在该列表上调用
ToArray
方法,该方法按照预期使用
new
关键字初始化数组。
static string[] LoadWords()
{
    string[] WordsArray = null; 
    Console.WriteLine("Please enter the name of a file:");

    do
    {
        try
        {  
            string filename = Console.ReadLine();

            if (File.Exists(filename))
                WordsArray = File.ReadAllLines(filename);
            else
                Console.WriteLine($"{Environment.NewLine} File does not exist, try again: ");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"{Environment.NewLine} Unknown exception, exiting. {ex.Message}");
            return null;
        }
    }
     while (WordsArray == null)

    return WordsArray;
}