gfppaste
gfppaste

Reputation: 1121

Conditional Streamwrite in C#

Say I have a list of member, each of which is a custom object:

public class pail
{
    public string milk;
    public string water;
    public string butter;
    public string beer;
}



public class AddToPail()
{
    private List<pail> _pailList = new List<pail>();
    PSVM(String[] args)
    {
        for(int i = 0; i < 200; i++)
        {
            pail newPail = new Pail();
            switch(i)
            {
                case 1:
                {
                    newPail.milk = "This pail has milk";
                }
                break;
                case 2:
                {
                    newPail.butter = "This pail has butter";
                }
                break;
                case 3:
                {
                    newPail.water = "This pail has water";
                }
                break;
                case 4:
                {
                    newPail.beer = "This pail has beer";
                }
                break;
            }
            _pailList.Add(newPail);
        }
        foreach (pail thisPail in _pailList)
        {
            using (StreamWriter SW = new StreamWriter(@"C:\pail.txt")
            {
                if (!thisPail.milk.IsNullOrEmpty())
                {
                    SW.WriteLine(thisPail.milk);
                }
                else if (!thisPail.butter.IsNullOrEmpty())
                {
                    SW.WriteLine(thisPail.butter);
                }
                else if (!thisPail.beer.IsNullOrEmpty())
                {
                    SW.WriteLine(thisPail.beer);
                }
                else if (!thisPail.water.IsNullOrEmpty())
                {
                    SW.WriteLine(thisPail.water);
                }
                else
                {
                    Console.Writeline("oops");
                }
            }
        }
    }
}

Say I want to set up a StreamWriter that only prints the true values without having to write a million if, else if, else statements... is there an easy way or library to do this in C#? I'm basically looking for a way to only print out true values in a neat, concise way. Does anyone have any advice as to how I should approach this?

Thank you very much!

EDIT So the ultimate goal of this is that I have an object that has around 20 members. The object is automatically populated, and the populating script can leave some of the members empty. I'd like to be able to print the members in a CSV format, and not have to have 20 if statements to see if a particular member in the object has been instantiated before outputting via the streamwriter.

Edit 2

I changed my code to be a little closer to what I needed it to do. Sorry for the previous poor explanation.

Upvotes: 0

Views: 711

Answers (4)

Francesco Baruchelli
Francesco Baruchelli

Reputation: 7468

Of course using a Dictionary could solve your problem , but I'm not really fond of this kind of solution, since it makes you lose some control over what you are putting in, e.g you could end up with a pail having airplanes... I'd refactor your code in something like this, trying to give every class its own responsabilities (BTW I don't like AddToPail as a class name, it's more a method name):

public class Pail
{
    public string milk;
    public string water;
    public string butter;
    public string beer;

   private bool everythingEmpty = true;

    public Pail(int i)
    {
            switch(i)
            {
                case 1:
                {
                    milk = "This pail has milk";
                    everythingEmpty = false;
                }
                break;
                case 2:
                {
                    butter = "This pail has butter";
                    everythingEmpty = false;
                }
                break;
                case 3:
                {
                    water = "This pail has water";
                    everythingEmpty = false;
                }
                break;
                case 4:
                {
                    beer = "This pail has beer";
                    everythingEmpty = false;
                }
                break;
            }
    }

    public void WriteToStream(StreamWriter SW)
    {
           if (everythingEmpty)
           {
               Console.Writeline("oops");
               return;
           }
           WriteToStream(milk, SW);
           WriteToStream(butter, SW);
           WriteToStream(beer, SW);
           WriteToStream(water, SW);
    }

    public static void WriteToStream(string content, StreamWriter SW)
    {
                if (!content.IsNullOrEmpty())
                {
                    SW.WriteLine(content);
                }
    }
}



public class AddToPail()
{
    private List<pail> _pailList = new List<pail>();
    PSVM(String[] args)
    {
        for(int i = 0; i < 200; i++)
        {
            pail newPail = new Pail(i);
            _pailList.Add(newPail);
        }
        foreach (pail thisPail in _pailList)
        {
            using (StreamWriter SW = new StreamWriter(@"C:\pail.txt")
            {
                thisPail.WriteToStream(SW);
            }
        }
    }
}

Upvotes: 1

Charleh
Charleh

Reputation: 14002

Can you just use a Dictionary where the key is the field name and the value is the fields value. This way you don't need to check if the output is filled or not - you just output all fields

Your populating script can populate the dictionary keys only if they are set

Then your streamwriter can just go

foreach(KeyValuePair<string, string> kvp in fieldsDict)
   sw.Write("Key: " + kvp.Key + ", Value: " + kvp.Value);

Or even just a list of string/or enum

e.g.

public class pail
{
    public List<string> Fields = new List<string>();
}


public class AddToPail()
{
    private List<pail> _pailList = new List<pail>();

    PSVM(String[] args)
    {
        for(int i = 0; i < 200; i++)
        {
            pail newPail = new Pail();
            switch(i)
            {
                case 1:
                {
                   newPail.Fields.Add("This pail has milk");
            }
            break;
         *** SNIP

Upvotes: 1

Kris Vandermotten
Kris Vandermotten

Reputation: 10201

If you just want to save some typing, use this extension method:

internal static class Extensions
{
    public static void WriteLineIf(this TextWriter tw, bool condition, string text)
    {
        if (condition)
        {
            tw.WriteLine(text);
        }
    }
}

But it looks like only one of those bools can be true, since you're using else if blocks.

In that case, use and enum

internal enum Pail
{
    Butter,
    Milk,
    Water,
    Beer
}

Upvotes: 1

Ethan Brown
Ethan Brown

Reputation: 27282

I think you should refactor your program a little bit. For starters, I would use an enum for bucket contents:

public enum EBucketContents { Milk, Water, Butter, Beer };

Then, instead of having a list of booleans, you can use a dictionary:

var pail = Dictionary<EBucketContents,bool>();

Now it's a simple matter to only output the ones that are true:

foreach( var kvp in pail.Where( x => x.Value ) ) {
    SW.WriteLine( "pail has " + kvp.Key.ToString().ToLower() )
}

Upvotes: 5

Related Questions