【问题标题】:Auto-incrementing C# container ID自动递增的 C# 容器 ID
【发布时间】:2011-04-05 06:40:07
【问题描述】:

如果我有一个对象列表,例如 List<Cake>,是否可以在 Cake 对象中包含一个 private int key,它将在我每次添加到列表时存储一个自动递增的值。

我想要这个的原因是我可以填充一个组合框,其中包含我列表中所有“蛋糕”的每个元素的唯一值,我不必自己输入。

例如:

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

您能否告知这是否可能(对于两种密钥类型)以及如何完成。另外,这是否是我的问题的糟糕解决方案。

非常感谢,

阿什利

【问题讨论】:

    标签: c# containers auto-increment


    【解决方案1】:

    每次创建 Cake 实例时,_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;
        }
    }

    【讨论】:

    • 感谢您的回复,但我更喜欢每个列表特定的键。
    • 您可以考虑使用 Dictionary 或 Dictionary 来代替列表。但是,您仍然需要自己为字典中的每个 Cake 项目提供密钥,可以使用上述方法,也可以使用自定义唯一密钥生成器。
    • 如果两个线程几乎同时尝试分配 Cakes,它们最终可能得到相同的 ID。您需要使用静态对象作为 _id = Last++; 操作周围的锁。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我通常认为这种编码风格是个坏主意。添加到列表时生成的 ID 是一种副作用,并不总是预期的(甚至不知道会发生)。副作用有时是必要的(实际上很多编程都依赖于它们),但它们也可能很棘手。例如,如果将同一个 Cake 对象添加到两个列表中会怎样?然后怎样呢?像这样的意外可能会导致代码难以调试。

      Slantroph 的想法是在创建时给所有 Cake 对象一个独特的想法,这并不坏,而且是一种非常常见的模式。但是你真的需要吗?您仍然可以使用 object.ReferenceEquals() 之类的方法来区分对象。也许您真正需要的是经过深思熟虑的EqualsGetHashcode 覆盖?

      【讨论】:

        【解决方案4】:

        听起来您正在尝试获取类似于在 RDBMS 表中找到的自动递增 ID。

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

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

        RDBMS 表和List&lt;T&gt; 之间的另一个重要区别是给定记录与单个表相关联。这不是对象在 C# 中的工作方式。它们都只是漂浮在内存中的“某处”。 List&lt;T&gt; 只是一个包含对其他对象的引用的对象。所以其他列表(实际上是其他类型的对象)可能持有对同一对象的引用。在语言层面上,没有人是另一个人的“所有者”。

        【讨论】:

        • 在客户端-服务器程序的情况下需要使用 id。您将数据发送到服务器,服务器执行一些操作并返回结果 - 一旦您从服务器获得结果,您如何知道该类型的对象在何处完成操作?答:某种形式的标识符传递给服务器并返回给客户端
        猜你喜欢
        • 2012-03-04
        • 2010-10-04
        • 2015-03-10
        • 1970-01-01
        • 2018-11-05
        • 1970-01-01
        • 2018-02-11
        • 2015-07-05
        • 2014-10-01
        相关资源
        最近更新 更多