If statement with multiple variables ending with a number

Viewed 308

Variables:

private string filePath1 = null;
private string filePath2 = null;
private string filePath3 = null;
private string filePath4 = null;
private string filePath5 = null;
private string filePath6 = null;
private string filePath7 = null;
private string filePath8 = null;
private string filePath9 = null;
private string filePath10 = null;

Current If statement

if (string.IsNullOrEmpty(filePath1))
{
    errors.Add("File Not Attached");
}

if (string.IsNullOrEmpty(filePath2))
{
    errors.Add("File Not Attached");
}
....

Question:

Instead of having multiple if statements, for each variable. How can I create 1 if statement to go through all these variables?

Something like this:

if (string.IsNullOrEmpty(filePath + range(1 to 10))
{
    errors.Add("File Not Attached");
}
7 Answers

You can achieve this using Reflection. This is obviously discouraged for this scenario, as the other answers provide better solutions, just wanted to show you it's doable the way you intended it to be done (which doesn't mean it's the correct way)

public class Test
{
    private string filePath1 = null;
    private string filePath2 = null;
    private string filePath3 = null;
}

Usage:

Test obj = new Test();

//loop through the private fields of our class
foreach (var fld in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
                                     .Where(x => x.Name.StartsWith("filePath"))) // filter
{
    if (string.IsNullOrEmpty(fld.GetValue(obj) as string))
    {
        errors.Add("File Not Attached in variable: " + fld.Name);
    }
}

In nearly all cases where you're using variables with a differently numbered suffix, you should really be using a collection (array, list, ...). This is one of those cases. I'll be using a list for this answer but any collection will suffice.

private List<string> filePaths = new List<string>()
                                 {
                                     "path1",
                                     "path2",
                                     "path3",
                                     "path4"
                                 };

You can then use a loop to iterate over your list:

foreach (string path in filePaths)
{
    if(String.IsNullOrEmpty(path))
        errors.Add("File not attached");
}

Create a new arraylist, add all file paths to it (or initialise it with all filepaths) and the loop over the elements in the array (using for-each loop). For each element, check if nullOrEmpty and if yes add to your errors string.

ArrayList arrlist = new ArrayList();
arrList.add(filePath1);
arrList.add(filePath2);
arrList.add(filePath3);
arrList.add(filePath4);
arrList.add(filePath5);
arrList.add(filePath6);
arrList.add(filePath7);
arrList.add(filePath8);
arrList.add(filePath9);
arrList.add(filePath10);

foreach (string element in arrList)
{
    if (string.IsNullOrEmpty(element)
    {
      errors.Add("File Not Attached");
    }
}

ps. You might want to print a new line after each error:

errors.Add("File Not Attached\n");
    // Create list
    List<string> filePaths = new List<string>;

    //Add path in list like 
    filePaths.add(filePath1);

    //Check for null path here

    foreach (string filepath in filePaths)
    {
        if (string.IsNullOrEmpty(filepath)
        {
          errors.Add("File Not Attached");
        }
    }

In order to treat all strings the same way they have to be in some collection.

using System.Linq;

...
string[] allPaths = new string[10];

// Do something with these ten paths...

if (allPaths.Any(x => string.IsNullOrEmpty(x))
    errors.Add("File Not Attached");

As stated every other answers, you should use a collection.

If you really want to stick with fields names, you can use reflection, but I strongly recommend to use collections over reflection :

// using System.Reflection;
// Below code is meant to be used in a method of the class that holds the fields.
for (int i = 1; i <= 10; i++)
{
    if (string.IsNullOrEmpty(this.GetType()
                                 .GetField($"filePath{i}",
                                           BindingFlags.NonPublic | BindingFlags.Instance)?
                                 .GetValue(this))
    {
        errors.Add("File Not Attached");
    }
}

If you can make those variable class fields i would vote for Innat3's Answer.

Bu if this is not possible and you can't make those variables class fields then i suggest to you do like following :

class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, int> names = new Dictionary<string,int>();


            for (int i = 0; i < 10; i++)
            {
                names.Add(String.Format("name{0}", i.ToString()), i);
            }

            var xx1 = names["name1"];
            var xx2 = names["name2"];
            var xx3 = names["name3"];
        }
    }

Because in c# we can't compute dynamically variable names.

Hope this helps.

Related