简体   繁体   中英

Pattern Matching with 8 conditions in C#: File.Exists returns false, but the file does exist

Consider the program from below. The idea should be as follows: In the Main method, AreAllArgumentsPassedAndValid() is called that checks certain parameters for correctness. The check is carried out using so-called tuple matching. A total of 7 + 1 conditions should be checked. For the sake of simplicity, I have replaced 7 of these conditions with boolean variables with permanently assigned values, because I am sure that they will be checked correctly. I only left the last condition as it appears in my original program. In this last condition, the string is checked whether it is not empty or zero and then checked whether the file exists (the string thus represents the path).

The problem: I have found that the file is never found if I have at least 8 conditions in my switch. But: As soon as I delete a condition from the switch, for example, cond7 , I only have 7 conditions in total and in this case the file is correctly searched for and a correct value is returned, depending on whether the file exists or not.

It also doesn't matter where I put my file - I tried to put the file directly under C:\ . It is not found there either. But if I call File.Exists separately, not in the return/switch, the search for the file works correctly.

My question is the following: What influence does the number of arguments in return/switch have on the correct work of File.Exists(oFileName) ? I've tried debugging the File.Exists(oFileName) method when I have 8 conditions in the switch, but that didn't bring me up to the solution.

Information about my PCs: All of them have Win 10 x64 and the same .NET version. And on all of them is the issue the same.

The whole program with 8 conditions in the return/switch:

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
                    };
            }
        }
    }
}

The AreAllArgumentsPassedAndValid method with only 7 conditions - in this case the program works as it should:

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
                };
}

When creating a tuple with 8 values, it starts to get weird . The better approach is to create an object with named properties, since I'd argue the tuple you have is impossible to read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM