views:

80

answers:

4

Hey,

If I have a list of objects, for example List<Cake>, is it possible to have a private int key in the Cake object that will store an auto-incremented value every time I add to the list.

My reason for wanting this is so that I can populate a combobox containing all the "Cakes" in my list with a unique value for each element that I don't have to input myself.

For example:

public class Cake
{
    private int _id;
    private string _name;

    public Cake(string name)
    {
        _name = name;
    }

    public int GetID()
    {
        return _id;
    }
}

List<Cake> myCakeList = new List<Cake>();

myCakeList.Add(new Cake("Sponge"));
myCakeList.Add(new Cake("Chocolate"));
myCakeList.Add(new Cake("Battenburg"));

myCakeList.ForEach(x => {Console.WriteLine(x.GetID());});

Ideally this code would return:

0000001
0000002
0000003

or (if I wanted a random id)

389hguhg907903
357fboib4969gj
fhgw90290682gg

Could you please advise if this is at all possible (for both key types) and how it can be done. Also, whether or not this is a terrible solution to my problem.

Many thanks in advance,

Ashley

+1  A: 

here the _id gets auto increased everytime you create an instance of a Cake

public class Cake
{
    private int _id;
    private string _name;
    private static LastID;
    public Cake(string name)
    {
        _name = name;
        _id = LastID++;
    }

    public int GetID()
    {
        return _id;
    }
}
Slantroph
Thanks for your response, however I would prefer a key that is specific to each list.
Ash
you might consider using a Dictionary<string, Cake> or Dictionary<int, Cake> instead of a list. but still, you'll need to provide the key for each Cake item in the dictionary by yourself, either by using a method like above or a by a custom unique key generator.
Slantroph
If two threads ever try to allocate Cakes at around the same time, they may end up with the same ID. You'd need to use a static object as a lock around the `_id = Last++;` operation.
Daniel Earwicker
A: 

I generally find this style of coding to be a bad idea. This ID generation on adding to a list is a side effect, and not always expected (or even known to be happening). Side effects are sometimes necessary (indeed a lot of programming relies on them), but they can be tricky too. For example, what if the same Cake object gets added to two lists? What then? Surprises like that can lead to code that is hard to debug.

Slantroph's idea of just giving all Cake objects a unique idea upon creation isn't bad, and is a pretty common pattern. But do you really need it? You can still tell objects apart with the likes of object.ReferenceEquals(). Perhaps what you really need is well thought out Equals and GetHashcode overrides?

Matt Greer
A: 

It sounds like you're trying to get something akin to an auto-incrementing ID as found in RDBMS tables.

The reason they are needed in an RDBMS is to allow a record in one table to identify a record in another table, by storing the ID of the other record.

This is not necessary in C# when dealing with objects in memory. You just have a field in on one object that holds a reference to another object.

Another important difference between RDBMS tables and List<T> is that a given record is associated with a single table. That's not how objects work in C#. They are all just floating "somewhere" in memory. A List<T> is merely an object that holds references to other objects. So other lists (and indeed other types of object altogether) may be holding references to the same object. No one is the "owner" of another at the language level.

Daniel Earwicker
A: 

Items in a list are accessed by index. Why not just use the index already in your list?

List<Cake> myCakeList = new List<Cake>();

myCakeList.Add(new Cake("Sponge"));
myCakeList.Add(new Cake("Chocolate"));
myCakeList.Add(new Cake("Battenburg"));

foreach (var i in Enumerable.Range(0, myCakeList.Length)) {Console.WriteLine(i);}
Joel Coehoorn