Declan
Declan

Reputation: 13

Check if instance of class exists with certain property

I have a list of classes, each with four properties:

public class BroncoClass
{
    public NPC npc { get; set; }
    public int TimeLeft { get; set; }
    public bool Gravity { get; set; }
    public bool Rotation { get; set; }
}
public List<BroncoClass>  BroncoList = new List<BroncoClass>();

I want to check if the list contains a class with a specific npc value, for example:

for (int i = 0; i < Main.npc.Length; i++) // For every alive npc
{
        if(BroncoList.contains a class where npc == Main.npc[i])
        {
        }
}

Haven't been able to find an answer online, any help is appreciated.

Upvotes: 1

Views: 1583

Answers (2)

Flydog57
Flydog57

Reputation: 7111

Very similar to @BradleyDotNET's answer. I just folded the factory into the class as static methods. I'm not saying this is right way to go, I'm just offering it as a solution to your question. Using static methods in the class seems closer to what the OP is asking about.

First, I needed an NPC class to get this to compile. Notice that it implements IEquatable so that I can compare instances for equality the way I want to (and that I override GetHashCode because that's a requirement).

public class NPC : IEquatable<NPC>
{
    private static int _indexKeeper = 0;
    public int Index { get; } = _indexKeeper++;

    public bool Equals(NPC other)
    {
        return Index == other?.Index;
    }

    public override int GetHashCode()
    {
        return Index.GetHashCode();
    }
}

With that, here's the BroncoClass (mostly untested):

public class BroncoClass
{
    private BroncoClass(int timeLeft, bool gravity, bool rotation)
    {
        Npc = new NPC();
        TimeLeft = timeLeft;
        Gravity = gravity;
        Rotation = rotation;
    }
    public NPC Npc { get; set; }
    public int TimeLeft { get; set; }
    public bool Gravity { get; set; }
    public bool Rotation { get; set; }

    private static List<BroncoClass> _instances = new List<BroncoClass>();
    public static BroncoClass Create(int timeLeft, bool gravity, bool rotation)
    {
        var bronco = new BroncoClass(timeLeft, gravity, rotation);
        _instances.Add(bronco);
        return bronco;
    }

    public static bool Remove(NPC npc)
    {
        var broncoFound = _instances.FirstOrDefault(b => b.Npc == npc);
        if (broncoFound == null)
        {
            return false;
        }

        _instances.Remove(broncoFound);
        return true;
    }

    public static BroncoClass Find(NPC npc)
    {
        return _instances.FirstOrDefault(b => b.Npc == npc);
    }

}

Upvotes: 1

BradleyDotNET
BradleyDotNET

Reputation: 61339

The real solution is to just keep a collection somewhere and use LINQ to query it. Presumably this collection would be easy to maintain as it would be the collection that is used for all other operations with BroncoClass.

After update to OP... You already have the list, just use list.Any(o => o.npc == testNpc) or whatever other predicate you may need.

However, if you really want to do the actual question:

Sounds like a reasonable usage of a factory pattern; but you will need to effectively do manual memory management. Your factory would be something like:

// Could be static, but I hate static. Don't use static.
public class BroncoFactory
{
     private List<BroncoClass> trackedObjects = new List<BroncoClass>();
     public BroncoClass New()
     {
         var newInstance = new BroncoClass();
         trackedObjects.Add(newInstance)
     }

     // Don't forget to call this or you'll leak!
     public void Free(BroncoClass instance)
     {
          trackedObjects.Remove(instance);
     }

     public bool ExistsWithNPC(NPC test)
     {
         return trackedObjects.Any(o => o.npc == test);
     }
}

Just really, really don't forget to call Free on an object when you are done with it.

Upvotes: 2

Related Questions