2010-08-28 3 views
0

Si j'ai une liste d'objets, par exemple List<Cake>, est-il possible d'avoir un private int key dans l'objet Cake qui stockera une valeur auto-incrémentée chaque fois que j'ajouterai à la liste.ID de conteneur C# à incrémentation automatique

La raison pour laquelle je veux cela est que je peux remplir une liste déroulante contenant tous les "Gâteaux" de ma liste avec une valeur unique pour chaque élément que je n'ai pas à saisir moi-même.

Par exemple:

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());}); 

Idéalement ce code renverrait:

0000001 
0000002 
0000003 

ou (si je voulais un identifiant aléatoire)

389hguhg907903 
357fboib4969gj 
fhgw90290682gg 

Pourriez-vous s'il vous plaît aviser si cela est dans la mesure du possible (pour les deux types de clés) et comment cela peut être fait. Aussi, que ce soit ou non une solution terrible à mon problème.

Un grand merci à l'avance,

Ashley

Répondre

0

Je trouve généralement ce style de codage à une mauvaise idée. Cette génération d'ID lors de l'ajout à une liste est un effet secondaire, et pas toujours attendu (ou même connu comme se produisant). Des effets secondaires sont parfois nécessaires (en effet beaucoup de programmation repose sur eux), mais ils peuvent aussi être difficiles. Par exemple, que se passe-t-il si le même objet Cake est ajouté à deux listes? Quoi alors? Des surprises comme celle-ci peuvent conduire à un code difficile à déboguer.

L'idée de Slantroph de donner à tous les objets Cake une idée unique lors de la création n'est pas mauvaise, et c'est un modèle assez commun. Mais en as-tu vraiment besoin? Vous pouvez toujours différencier les objets avec object.ReferenceEquals(). Peut-être ce que vous avez vraiment besoin est bien pensé Equals et GetHashcode dérogations?

3

ici le _id obtient automatiquement augmenté chaque fois que vous créez une instance d'un gâteau

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; 
    } 
}
+0

Merci pour votre réponse, mais je préférerais une clé qui est spécifique à chaque liste. – Ash

+0

vous pourriez envisager d'utiliser un dictionnaire ou Dictionary au lieu d'une liste. Cependant, vous devrez fournir vous-même la clé de chaque élément Cake dans le dictionnaire, soit en utilisant une méthode comme ci-dessus, soit en utilisant un générateur de clé unique personnalisé. – Slantroph

+0

Si deux threads tentent d'allouer Cakes à peu près au même moment, ils peuvent se retrouver avec le même ID. Vous devez utiliser un objet statique comme verrou autour de l'opération '_id = Last ++; –

0

Il semble que vous essayez d'obtenir quelque chose qui s'apparente à un ID auto-incrémenté tel qu'il se trouve dans les tables de SGBDR.

La raison pour laquelle ils sont nécessaires dans un SGBDR est de permettre à un enregistrement dans une table d'identifier un enregistrement dans une autre table, en stockant l'ID de l'autre enregistrement.

Ceci n'est pas nécessaire en C# pour traiter des objets en mémoire. Vous avez juste un champ sur un objet qui contient une référence à un autre objet.

Une autre différence importante entre les tables RDBMS et List<T> est qu'un enregistrement donné est associé à une seule table. Ce n'est pas comme ça que les objets fonctionnent en C#. Ils flottent tous "quelque part" en mémoire. Un List<T> est simplement un objet qui contient des références à d'autres objets. Ainsi, d'autres listes (et même d'autres types d'objets) peuvent contenir des références au même objet. Personne n'est le «propriétaire» d'un autre au niveau de la langue.

+3

une situation où l'utilisation d'un identifiant serait nécessaire dans le cas d'un programme client-serveur. Vous envoyez les données au serveur, le serveur effectue certaines opérations et renvoie le résultat - une fois que vous obtenez le résultat du serveur, comment sauriez-vous quel objet de ce type les opérations ont été effectuées? Réponse: une forme d'identifiant transmise au serveur et retournée au client – 537mfb

1

Les éléments d'une liste sont accessibles par index. Pourquoi ne pas simplement utiliser l'index déjà dans votre liste?

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);} 
Questions connexes