自动增加C#容器ID

问题描述:

如果我有一个对象列表,例如List<Cake>,Cake对象中可能有一个private int key,每次添加到列表中时都会存储一个自动递增的值。自动增加C#容器ID

我之所以想要这样做,是为了让我可以在列表中填充包含所有“蛋糕”的组合框,并为每个我不必输入自己的元素设置一个唯一值。

例如:

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

理论上讲,该代码将返回:

0000001 
0000002 
0000003 

或者(如果我想要一个随机ID)

389hguhg907903 
357fboib4969gj 
fhgw90290682gg 

能否请您指教,如果这是尽可能(对于两种关键类型)以及如何完成。此外,这是否是对我的问题的可怕解决方案。

提前许多感谢,

阿什利

我通常发现编码是一个坏的这种风格的实例自动每次增加理念。添加到列表中的这种ID生成是副作用,并不总是预期的(或者甚至已知正在发生)。副作用有时是必需的(事实上很多编程依赖于它们),但它们也可能非常棘手。例如,如果同一个Cake对象被添加到两个列表中会发生什么?然后怎样呢?这样的惊喜会导致难以调试的代码。

Slantroph的想法是在创建时给所有Cake对象一个独特的想法并不差,而且是一个很常见的模式。但你真的需要它吗?你仍然可以用object.ReferenceEquals()之类的东西来区分对象。也许你真的需要的是很好的想法EqualsGetHashcode覆盖?

这里_id让你创建一个蛋糕

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

感谢您的回复,但我更喜欢每个列表特定的密钥。 – Ash 2010-08-28 20:54:55

+0

您可能会考虑使用Dictionary 或Dictionary 而不是列表。但是仍然需要使用上述方法或通过自定义唯一密钥生成器来为字典中的每个Cake项目提供密钥。 – Slantroph 2010-08-28 21:06:03

+0

如果两个线程尝试在大约同一时间分配蛋糕,它们可能会以相同的ID结束。您需要使用静态对象作为'_id = Last ++;'操作的锁。 – 2010-08-28 21:27:35

听起来好像你正在试图获得类似于RDBMS表中的自动递增ID的东西。

它们在RDBMS中需要的原因是允许一个表中的记录通过存储另一个记录的ID来识别另一个表中的记录。

在处理内存中的对象时,这在C#中不是必需的。您只需在一个对象上有一个字段,该对象持有对另一个对象的引用。

RDBMS表和List<T>之间的另一个重要区别是给定记录与单个表相关联。这不是C#中的对象的工作方式。他们都只是浮在记忆中的“某个地方”。 A List<T>仅仅是保存对其他对象的引用的对象。所以其他列表(实际上是其他类型的对象)可能持有对同一对象的引用。没有人是语言层面的另一个“拥有者”。

+3

一种情况是,在客户端服务器程序的情况下,需要使用id。您将数据发送到服务器,服务器执行一些操作并返回结果 - 一旦从服务器获得结果,您如何知道该类型的操作在哪里完成?答:传递给服务器并回到客户端的某种形式的标识符 – 537mfb 2012-04-24 14:59:27

列表中的项目按索引访问。为什么不直接使用列表中的索引?

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