user5004883
user5004883

Reputation:

iteration over a bunch of objects

I have a eight objects that are sub classes of a super class. They all share the same fields and properties. What I am wanting to do is somehow iterate over this group of objects and find the first one with its Status field set to false then update some other fields associated with that object.

I have been trying to accomplish this with a string of if statements. Its not very pretty and it only works one time through the group of objects.

if (!Light7.Status)
            {
                if (!Light6.Status)
                {
                    if (!Light5.Status)
                    {
                        if (!Light4.Status)
                        {
                            if (!Light3.Status)
                            { 
                                if (!Light2.Status)
                                {
                                    if (!Light1.Status)
                                    {
                                        if (!Light0.Status)
                                        {
                                            Light0.Email = newId;
                                            Light0.Status = true;
                                            Light0.Index = Id.IndexOf(newId);
                                            Light0.lightStart();
                                            Light1.Status = true;
                                        }
                                    }
                                    else
                                    {
                                        Light1.Email = newId;
                                        Light1.Status = true;
                                        Light1.Index = Id.IndexOf(newId);
                                        Light1.lightStart();
                                        Light2.Status = true;
                                    }
                                }
                                else
                                {
                                    Light2.Email = newId;
                                    Light2.Status = true;
                                    Light2.Index = Id.IndexOf(newId);
                                    Light2.lightStart();
                                    Light3.Status = true;
                                }
                            }
                            else
                            {
                                Light3.Email = newId;
                                Light3.Status = true;
                                Light3.Index = Id.IndexOf(newId);
                                Light3.lightStart();
                                Light4.Status = true;
                            }
                        }
                        else
                        {
                            Light4.Email = newId;
                            Light4.Status = true;
                            Light4.Index = Id.IndexOf(newId);
                            Light4.lightStart();
                            Light5.Status = true;
                        }
                    }
                    else
                    {
                        Light5.Email = newId;
                        Light5.Status = true;
                        Light5.Index = Id.IndexOf(newId);
                        Light5.lightStart();
                        Light6.Status = true;
                    }
                }
                else
                {
                    Light6.Email = newId;
                    Light6.Status = true;
                    Light6.Index = Id.IndexOf(newId);
                    Light6.lightStart();
                    Light7.Status = true;
                }
            }
            else
            {
                Light7.Email = newId;
                Light7.Status = true;
                Light7.Index = Id.IndexOf(newId);
                Light7.lightStart();
            }

Is there a better way to achieve what I am looking to do? I am about two weeks into my journey with c# so I apologize for my ignorance.

EDIT: Looks like I didn't explain this enough.

Background: I have a little piece of technology called a BlinkStick and I am trying to make it a notification light for Outlook via an Add-in. What I want to happen is when the first email comes in it turns on light 1. Then when the second email comes in it turns on light 2, etc. When the status of the email goes from unread to read then it turns of the light that has been associated to it. If there are other lights active it moves those lights to the previous space. So Light 2 would move to Light 1, and Light 3 would move to Light 2 for example.

Here is the class that all the lights are based off of.

class LightSuper
{
     public LightSuper()
    {

    }

    public LightSuper(byte i, bool e)
    {
        i = index;
        e = Status;
    }

    private static string email;

    public static string Email
    {
        get { return email; }
        set { email = value; }
    }

    private static byte index;

    public static int Index
    {
        get { return index; }
        set { index = Convert.ToByte(value+1); }
    }

    private static bool status;

    public static bool Status
    {
        get { return status; }
        set { status = value; }
    }

    public static void lightStart()
    {
        Thread start = new Thread(() => lightLoop(ref index, ref status));
        start.IsBackground = true;
        start.Start();
    }

    private static void lightLoop(ref byte index, ref bool state)
    {
        Stopwatch timer = new Stopwatch();

        BlinkStick device = BlinkStick.FindFirst();
        if (device != null && device.OpenDevice())
        {
            timer.Start();
            while (state)
            {
                if (timer.Elapsed.Minutes < 3)
                {

                    device.SetColor(0, index, "green");
                    Thread.Sleep(500);
                    device.SetColor(0, index, "black");
                    Thread.Sleep(500);

                }
                if (timer.Elapsed.Minutes >= 3 && timer.Elapsed.Minutes < 5)
                {
                    device.SetColor(0, index, "yellow");
                    Thread.Sleep(375);
                    device.SetColor(0, index, "black");
                    Thread.Sleep(375);
                }
                if (timer.Elapsed.Minutes >= 5)
                {
                    device.SetColor(0, index, "red");
                    Thread.Sleep(250);
                    device.SetColor(0, index, "black");
                    Thread.Sleep(250);
                }
            }
        }
    }
}

class Light0 : LightSuper
{
    public Light0()
    {

    }
}

class Light1 : LightSuper
{
    public Light1()
    {

    }
}

class Light2 : LightSuper
{
    public Light2()
    {

    }
}

class Light3 : LightSuper
{   
    public Light3()
    {

    }
}

class Light4 : LightSuper
{
    public Light4()
    {

    }
}


class Light5 : LightSuper
{
    public Light5()
    {

    }
}

class Light6 : LightSuper
{
    public Light6()
    {

    }
}

class Light7 : LightSuper
{
    public Light7()
    {

    }
}

I found that if I create a new instance of SuperLight every single time an email comes in I couldn't edit that specific instance directly and still be able to update the while loop in lightLoop without turning all the lights off. So I created eight sub classes so that each class object can be edited individually.

If there is a better way to do this I am all ears.

Upvotes: 0

Views: 92

Answers (3)

AzNjoE
AzNjoE

Reputation: 733

The logical problem with your snippet is that if light7's status is false then it will go to the nested if, it won't reach the else statement where it will set the corresponding info, which is what you want. So if all of the statuses are false, only Light0 will have its properties changed. Logically you'd want your if statements to not have the ! in this case since if they are true, you don't want that Light's properties to be changed, you'd just want to check the next one.

Additionally, it looks like your lights are each individual classes, each with the exact same properties. I'd definitely look into how to just create a single class and create objects from that single class.

Documentation on objects:

https://msdn.microsoft.com/en-us/library/ms173110.aspx

I would look into loops and collections, specifically the for loop and lists.

Documentation for both:

https://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/ch45axte.aspx

You can reduce this entire code snippet to about 10 lines.

I would first create a "collection" of your objects in a list like so:

List<Light> lights = new List<Light>;

And then, add your light objects to the list:

lights.add(light) replacing light with each light and copying this line for each addition.

Then you would want to "iterate" or loop over each object in the list like so:

foreach (int index = 0; index < lights.Count()-1; index++)
{
    if (!lights[i].Status)
    {
          lights[i].Email = newId;
          lights[i].Status = true;
          lights[i].Index = Id.IndexOf(newId);
          lights[i].lightStart();
          lights[i+1].Status = true;
          break;
    }
}

In this case, you'd want the ! in the if statement because if the status is false it will go into the if statement, since the ! converts the result of the condition to true. Vice versa, if true, it will become false and just continue going through the loop.

The break; statement in the last line of the if statement block, will stop us from searching through the list, since it 'breaks' out of the loop.

Upvotes: 1

SteveR
SteveR

Reputation: 199

LINQ is a great tool for this kind of task. Your code might look something like this:

List<SuperClass> lightList = {...} //Add light1, light2, etc to the list.
SuperClass light = lightList.FirstOrDefault(l => !l.Status);
if (light != null)
{
    light.Email = newId;
    //Set rest of proprties
}

Or, if you wanted to update ALL objects in the list where Status == false

List<SuperClass> lightList = {...} //Add light1, light2, etc to the list. You may also want to order this list?
foreach(SuperClass light in lightList.Where(l => !l.Status))
{
    light.Email = newId;
    //Set rest of proprties
}

Upvotes: 2

willaien
willaien

Reputation: 2797

Use LINQ, with a collection of a particular class. Example:

var lights = new List<Light>();
//Insert logic to add lights to the collection (eg. lights.Add(new Light());)
var firstLight = lights.FirstOrDefault(light => !light.Status);
if (firstLight != null)
{
    firstLight.Email = newId;
    firstLight.Status = true;
    firstLight.Index = Id.IndexOf(newId);
    firstLight.lightStart();
    firstLight.Status = true;
}

Upvotes: 0

Related Questions