Home > Software design >  Custom dictionary class in c#
Custom dictionary class in c#

Time:10-19

I am trying to create a custom dictionary with some methods. I created a struct containing the information for lanes in my game. One information tells me if there is an enemy in the lane(Occupied) and the other if we completed that lane so no more enemies will come there(Completed).

I am able to get the initial information out, but cannot update them with my methods. I construct it by adding all 7 lanes, where none of them are either occupied or completed. Then throughout my game, I would like to mark them either as completed or occupied or free, but even after a lot of time searching around, I couldn't figure out the proper way to call for an update of these items inside my laneInfo property.

public struct laneInfo
{
    public bool Occupied;
    public bool Completed;
}

public class laneInfoClass : Dictionary<int, laneInfo>
{
    public laneInfo laneinfo;

    public laneInfoClass()
    {
        for(int i = 0; i <= 6; i  )
        {
            this.Add(i, false, false);
        }
    }
    public void Add(int key, bool occupied, bool completed)
    {
        laneinfo.Occupied = occupied;
        laneinfo.Completed = completed;
        this.Add(key, laneinfo);
    }
    public void Complete()
    {
        laneinfo.Completed = true;
    }
    public void Occupy()
    {
        laneinfo.Occupied = true;
    }
    public void Free()
    {
        laneinfo.Occupied = false;
    }
}

Thanks!

CodePudding user response:

Its fairly rare that your class would inherit from a dictionary/list/collection (why?), more often than not what you are actually modelling is a class which has an instance member which is that same dictionary/list/collection.

In addition, you need some way to notify your class which particular lane you're trying to update, you use an integer key so work with that:

public struct LaneInfo
{
    public bool Occupied {get;set;}
    public bool Completed {get;set;}
}

public class LaneInfoContainer
{
    private Dictionary<int, LaneInfo> laneInfoDict = new Dictionary<int, LaneInfo>();

    public LaneInfoContainer()
    {
        for(int i = 0; i <= 6; i  )
        {
            this.Add(i, false, false);
        }
    }
    public void Add(int key, bool occupied, bool completed)
    {
        var laneInfo = new LaneInfo();
        laneinfo.Occupied = occupied;
        laneinfo.Completed = completed;
        this.laneInfoDict.Add(key, laneinfo);
    }
    public void Complete(int key)
    {
        laneInfoDict[key].Completed = true;
    }
    public void Occupy(int key)
    {
        laneInfoDict[key].Occupied = true;
    }
    public void Free(int key)
    {
        laneInfoDict[key].Occupied = false;
    }
}

I suspect you might also need some way to read the info about your lanes too, add methods such as

public bool IsComplete(int key)
{
    return laneInfoDict[key].Complete;
}

CodePudding user response:

The answer to your question is that you should not use a Dictionary. Iterating a List<T>.Contains is faster than Dictionary<TKey, TValye> lookup for 7 items, especially if you are accessing them by index integer 0-6.

Part from that, Dictionary<TKey, TValue> is already generic and so there is no need to inherit from it. Sometimes you would wrap it, for various reasons (one might be locking). But if it is just for a few methods you can simply add extension methods to the Dictionary<int, LaneInfo>.

public static class LaneExtensionMethods
{
    public static bool IsComplete(this Dictionary<int, LaneInfo> dictionary, int key)
    {
        return dictionary[key].Complete;
    }
}

// Use
var d = new Dictionary<int, LaneInfo>();
var isComplete = d.IsComplete(1);

I often replace the int with a type to avoid bugs and confusion in code. This would in your case also allow for specialized extension methods. Casting has zero CPU cost (its just cosmetics in code).

public enum LaneId : Int32 { }

public static class LaneExtensionMethods
{
    public static bool IsComplete(this Dictionary<LaneId, LaneInfo> dictionary, LaneId key)
    {
        return dictionary[key].Complete;
    }
}

// Use
var d = new Dictionary<LaneId, LaneInfo>();
var laneId = (LaneId)1; // We cast from integer to LaneId, but use LaneId type everywhere in our app
var isComplete = d.IsComplete(laneId);
  •  Tags:  
  • c#
  • Related