Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#:我是否以正确的方式验证文件类型和使用goto?_C# - Fatal编程技术网

C#:我是否以正确的方式验证文件类型和使用goto?

C#:我是否以正确的方式验证文件类型和使用goto?,c#,C#,我有代码来保存一个文件,比如 SaveFileDialog dialog = new SaveFileDialog(); dialog.Filter = "Text files|*.txt"; SaveDialog: if ((bool)dialog.ShowDialog()) { if (System.IO.Path.GetExtension(dialog.FileName) != ".txt") { MessageBox.Show("You must select

我有代码来保存一个文件,比如

SaveFileDialog dialog = new SaveFileDialog();
dialog.Filter = "Text files|*.txt";

SaveDialog:
if ((bool)dialog.ShowDialog()) {
    if (System.IO.Path.GetExtension(dialog.FileName) != ".txt") {
        MessageBox.Show("You must select a .txt file");
        dialog.FileName = "";
        goto SaveDialog;
    }
    File.WriteAllText(dialog.FileName, txtEditor.Text);
}

我读到我不应该使用goto。我可以使用do/while并检查是否选择了有效的扩展,但这将添加大量不必要的代码。我觉得这更整洁。还是有更好/更正确的方法?

我建议如下:

using (SaveFileDialog dialog = new SaveFileDialog())
{
    dialog.Filter = "Text files|*.txt";
    while(dialog.ShowDialog() == DialogResult.OK)
        if (System.IO.Path.GetExtension(dialog.FileName).ToLowerInvariant() != ".txt")
            MessageBox.Show("You must select a.txt file");
        else // file is ok
        {
            File.WriteAllText(dialog.FileName, txtEditor.Text);
            break;
        }
 }
using (SaveFileDialog dialog = new SaveFileDialog()) {
    dialog.Filter = "Text files|*.txt";

    while (true) {
        if (dialog.ShowDialog() == DialogResult.OK) {
            if (!System.IO.Path.GetExtension(dialog.FileName).Equals(".txt", StringComparison.InvariantCultureIgnoreCase)) {
                MessageBox.Show("You must select a .txt file");
            }
            else {
                File.WriteAllText(dialog.FileName, txtEditor.Text);
                break; 
            }          
        }
        else break;
    }
}
虽然使用goto语句有正当的理由,但在这种情况下,可以避免使用goto语句,并用更具可读性的解决方案替换它


还请注意,不应将DialogResult(ShowDialog()的返回值)强制转换为bool。

DialogResult不能强制转换为布尔值:p这么多年以后,我已经忘记了这个关键词。@seave:在WPF中,
ShowDialog()
的结果是boolean@jiewmeng:这是WPF还是winforms?@Matt Ellen:你是对的(事实上它可以为null,这可以解释演员阵容),出于某种原因,我假设他使用的是winforms。+1,但那家伙在那里做什么?:-)关于使用的另一个好处是,正确地调用Dispose。我的错误,从早期的想法中继承过来。这就是我要建议的解决方案。但老实说,虽然我不喜欢在存在替代方法时看到“goto”,但就可读性而言,无限循环并没有提供更多。我仍然认为,就可读性而言,break/continue比goto更优雅。我发现使用goto的唯一合法案例是在switch语句中,您可以使用“goto案例[label]”实现超集/子集逻辑。@Bradley Smith。不,即使那样也很糟糕。如果您两次使用同一段代码,请使用方法调用。如果您未使用
而(true)
,我将对此答案进行投票。将下一个条件放入while条件,就可以开始了。如果用户按了“取消”,他无论如何都不会保存文件。你完全正确。修正了。。。还添加了“使用”语句,正如布拉德利的回答所示。。。好主意。我收到一个错误消息,说using中使用的类型必须隐式转换为
System.IDisposable
。此外,没有对话框结果。好的,我的答案适用于winforms,在winforms中,SaveFileDialog实现IDisposable。我不熟悉WPF,因此如果此错误仍然存在,只需删除“using”语句即可,因为这是WPF,请将“while”条件更改为:while((bool)dialog.ShowDialog())