简体   繁体   中英

C# structure for If.. And If… And If

I am using Visual Studio 2013 Express and I am new to Visual C#. I am sure there is a better way to do what I am trying and I would appreciate any suggestions.

The code I'm trying to write evaluates a series of tests and sets a flag only if all tests = TRUE. I'm currently using six nested if structures to get this done and, while it works, I'm looking for a cleaner, more professional solution. Here's the sample (shortened to three levels for this post):

private const string sDrive = "D:\\";
private const string sFolder = "FTP\\";
private const string sDivFolder = "ABC";
private static bool bSanity = false;

private static void SanityCheck()
{
    if (Directory.Exists(sDrive))
    {
        if (Directory.Exists(sDrive + sFolder))
        {
            if (Directory.Exists(sDrive + sFolder + sDivFolder))
            {
                bSanity = true;
            }
            else
            {
                Console.WriteLine("FATAL: Div folder doesn't exist.");
            }
        }
        else
        {
            Console.WriteLine("FATAL: Root folder doesn't exist.");
        }
    }
    else
    {
        Console.WriteLine("FATAL: Disk drive doesn't exist.");
    }
}  

The main issue is whether you need to keep the same error reporting you have now. In general, if that is required, I think this is simpler to handle by inverting the cases. That will allow you to remove the nesting by using if / else if :

private static void SanityCheck()
{ 
    if (!Directory.Exists(sDrive))
    {
       Console.WriteLine("FATAL: Disk drive doesn't exist.");
    }
    else if (!Directory.Exists(Path.Combine(sDrive, sFolder))
    {
       Console.WriteLine("FATAL: Root folder doesn't exist.");
    }
    else if (!Directory.Exists(Path.Combine(sDrive, sFolder, sDivFolder))
    {
        Console.WriteLine("FATAL: Div folder doesn't exist.");
    }
    else
    {
        bSanity = true;
    }
}  

If the detailed error reporting is not required, you can just check for the lowest level folder directly:

private static void SanityCheck()
{

    if (Directory.Exists(Path.Combine(sDrive, sFolder, sDivFolder))
         bSanity = true;
    else
        Console.WriteLine("FATAL: Drive or folder doesn't exist.");
}
if (Directory.Exists(sDrive) && Directory.Exists(sDrive + sFolder) && Directory.Exists(sDrive + sFolder + sDivFolder))
{
    bSanity = true;
}
else
{
    Console.WriteLine("FATAL: Disk drive doesn't exist.");
}

&& is an early exit operator.

How about using a loop and an array?

// set path array
var paths = new[] { sDrive, sFolder, sDivFolder };

// use StringBuilder for faster string concatenation
var sb = new StringBuilder();

foreach (var p in paths)
{
    // append next part of the path
    sb.Append(p);

    // check if it exists
    if (!Directory.Exists(sb.ToString()))
    {
        // print info message and return from method, because path is incorrect
        Console.WriteLine("FATAL: \"{0}\" path doesn't exist.", sb.ToString());
        return;
    }
}

// we are here, so the whole path works and we can set bSanity to true
bSanity = true;

You can easily manipulate how deap the check is by changing array length. And it will print you exactly what part of the path is not correct.

This isn't exactly the same behaviour as the original, but it is much simpler.

if (Directory.Exists(Path.Combine(sDrive, sFolder, sDivFolder))
    bSanity = true;
else
    Console.WriteLine("FATAL: Div folder doesn't exist.");

So one possible cleaner solution might be this:

private static List<Tuple<string, string>> _dir = new List<Tuple<string, string>>
{
    Tuple.Create(@"D:\", "FATAL: Disk drive doesn't exist."),
    Tuple.Create("FTP", "FATAL: Root folder doesn't exist."),
    Tuple.Create("ABC", "FATAL: Div folder doesn't exist."),
}

private static void SanityCheck()
{
    var path = string.Empty;
    foreach (var t in _dir)
    {
        path = Path.Combine(path, t.Item1);
        if (!Directory.Exists(path))
        {
            Console.WriteLine(t.Item2);
            break;
        }
    }
}

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