【问题标题】:Pattern Matching with 8 conditions in C#: File.Exists returns false, but the file does existC#中8个条件的模式匹配:File.Exists返回false,但文件确实存在
【发布时间】:2020-08-10 18:51:28
【问题描述】:

从下面考虑程序。思路应该是这样的:在Main方法中,调用AreAllArgumentsPassedAndValid()来检查某些参数的正确性。使用所谓的元组匹配进行检查。总共应检查 7 + 1 个条件。为简单起见,我已将其中 7 个条件替换为具有永久赋值的布尔变量,因为我确信它们会被正确检查。我只留下了原始程序中出现的最后一个条件。在最后一个条件中,检查字符串是否为空或不为零,然后检查文件是否存在(因此字符串表示路径)。

问题:我发现如果我的开关中至少有 8 个条件,则永远找不到该文件。但是:一旦我从开关中删除一个条件,例如cond7,我总共只有 7 个条件,在这种情况下,文件被正确搜索并返回正确的值,具体取决于文件是否存在与否。

我将文件放在哪里也没有关系 - 我试图将文件直接放在C:\ 下。那里也找不到。但如果我单独调用File.Exists,而不是在返回/切换中,则文件搜索工作正常。

我的问题如下:return/switch 中的参数数量对File.Exists(oFileName) 的正确工作有什么影响?当我在 switch 中有 8 个条件时,我尝试调试 File.Exists(oFileName) 方法,但这并没有让我找到解决方案。

关于我的 PC 的信息:它们都具有 Win 10 x64 和相同的 .NET 版本。所有这些问题都是一样的。

return/switch中有8个条件的整个程序:

using System;
using System.IO;

namespace PatternMatchingTest
{
    class Program
    {
        private static class Constants
        {
            public const string ProgramSide = "PROGRAM_SIDE";
            public const string OldFileName = "OLD_FILE_NAME";
            public const string NewFileName = "NEW_FILE_NAME";
        }
        
        static void Main(string[] args)
        {
            string oldFilePath = @"C:\Users\ADMINI~1\AppData\Local\Temp\Test.txt";
            
            Console.WriteLine(AreAllArgumentsPassedAndValid());
            Console.ReadKey();
            
            string AreAllArgumentsPassedAndValid()
            {
                string oFileName = oldFilePath;
                bool cond1 = true, cond2 = true, cond3 = true, cond4 = true, cond5 = true, cond6 = false, cond7 = false;
                return (cond1,
                        cond2,
                        cond3,
                        cond4,
                        cond5,
                        cond6,
                        cond7,
                        !string.IsNullOrEmpty(oFileName) && File.Exists(oFileName))
                    switch
                    {
                        (false, _, _, _, _, _, _, _) => $"Invalid number of arguments. 3 arguments are expected.",
                        (_, false, _, _, _, _, _, _) => $"Missing {Constants.ProgramSide} argument.",
                        (_, _, false, _, _, _, _, _) => $"Missing {Constants.OldFileName} argument.",
                        (_, _, _, false, _, _, _, _) => $"Missing {Constants.NewFileName} argument.",
                        (_, _, _, _, false, _, _, _) => $"Argument {Constants.ProgramSide} has invalid value.",
                        (_, _, _, _, _, true, _, _) => $"Argument {Constants.OldFileName} has invalid value: null or empty. Expected: path to a file.",
                        (_, _, _, _, _, _, true, _) => $"Argument {Constants.NewFileName} has invalid value: null or empty. Expected: path to a file.",
                        (_, _, _, _, _, _, _, false) => $"File {oFileName} does not exist.",
                        (true, true, true, true, true, false, false, true) => string.Empty
                    };
            }
        }
    }
}

只有 7 个条件的 AreAllArgumentsPassedAndValid 方法 - 在这种情况下,程序可以正常工作:

string AreAllArgumentsPassedAndValid()
{
    string oFileName = oldFilePath;
    bool cond1 = true, cond2 = true, cond3 = true, cond4 = true, cond5 = true, cond6 = false, cond7 = false;
        return (cond1,
                cond2,
                cond3,
                cond4,
                cond5,
                cond6,

                !string.IsNullOrEmpty(oFileName) && File.Exists(oFileName))
                switch
                {
                    (false, _, _, _, _, _, _) => $"Invalid number of arguments. 3 arguments are expected.",
                    (_, false, _, _, _, _, _) => $"Missing {Constants.ProgramSide} argument.",
                    (_, _, false, _, _, _, _) => $"Missing {Constants.OldFileName} argument.",
                    (_, _, _, false, _, _, _) => $"Missing {Constants.NewFileName} argument.",
                    (_, _, _, _, false, _, _) => $"Argument {Constants.ProgramSide} has invalid value.",
                    (_, _, _, _, _, true, _) => $"Argument {Constants.OldFileName} has invalid value: null or empty. Expected: path to a file.",
                    (_, _, _, _, _, _, false) => $"File {oFileName} does not exist.",
                    (true, true, true, true, true, false,  true) => string.Empty
                };
}

【问题讨论】:

  • 您在dotnetfiddle.net with that code 上收到一条有趣的错误消息“操作可能会破坏运行时的稳定性。”。也许坚持类型。
  • 我认为解决这个问题的一种方法是创建子元组,这样单个元组就不会超过 7 个项目。像((c1, c2, c3, c4), (c5, c6, c7, c8)) 这样你就可以像((true, _, _, _), _) 这样比较短一点。

标签: c#


【解决方案1】:

当创建一个有 8 个值的元组时,它是starts to get weird。更好的方法是创建一个具有命名属性的对象,因为我认为您拥有的元组是无法读取的。

【讨论】:

  • 那是Tuple 类,OP 正在处理值元组。
  • @juharr 他们被定义为in the same way
  • @GSerg 是的,我只是在查找源代码,所以会存在同样的问题。
  • @Noah Stahl 好的,明白了。我忽略了 8 个项目的这个限制。
猜你喜欢
  • 2017-08-16
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 2010-10-29
  • 2011-10-19
  • 2019-12-30
  • 2012-10-22
  • 2016-01-13
相关资源
最近更新 更多