【问题标题】:c# how to increment id for each instance of class automaticallyc#如何自动为每个类实例增加id
【发布时间】:2020-10-27 12:37:46
【问题描述】:

用户插入 KID NAME,代码实例化一个对象并将其添加到对象列表中。 如何自动从 1 开始给每个对象一个唯一的编号,这样第一个 KID(object) 的编号为 1,第二个 KID 的编号为 2,依此类推。 我尝试过这样的事情,但结果是“stackoverflow”。 课堂应该是怎样的?

class Kid
    {
        public string KidName{ get; set; }
        private static int Number { get; set; }
        public int KidNumber { get; set; }
        
        public Kid (string name)
        {
            this.KidName = name;
            Number++;
            this.KidNumber = Number;
        }
    }

【问题讨论】:

  • 这种方法乍一看似乎没问题,只要你不处理多线程(使用这样的静态属性不是线程安全的,但不会导致StackOverflowException)。您可能在代码的其他地方递归地实例化或无限期地调用。
  • 请向我们展示您实例化类的代码。

标签: c# object constructor


【解决方案1】:

您的代码在我的设备上成功运行。 也许您有其他原因的“stackoverflow”?

如果您只需要识别 Kid 类,另一种方法是使用 Guid:

class Kid
{
    public string KidName { get; set; }
    public Guid KidNumber { get; set; }

    public Kid(string name)
    {
        this.KidName = name;
        this.KidNumber = Guid.NewGuid();
    }
}

【讨论】:

  • “更好”是一个解释问题。例如,它的生成速度要慢得多(也有报告称在非 Windows 平台上性能更差。)如果你想要一个人类可读的 ID,它就不是很好,并且占用了更多的空间。因此,这取决于您想要实现的目标是否“更好”。 “另类”会是一个更好的描述。
【解决方案2】:

您的示例中没有任何内容可以引发StackOverflowException。当您直接或间接(通过中间体)递归地重复调用相同的方法,或者当您具有与实例本身相同类型的实例级字段(前者的特殊情况)时,就会发生 Stackoverflows。您的示例中没有显示任何一种情况,因此它一定是由于您显示的代码的其他外部。您的代码可能最多可能展示的是OverflowExceptionif you were in a checked context

也就是说,您的方法乍一看还可以,但明显的缺陷是它不是线程安全的。理论上,两个实例可能以相同的KidNumber 告终。您可以通过使用Interlocked 类来修复那个

using System.Threading;

class Kid
{
    private static int _counter;
    public string KidName { get; set; }
    public int KidNumber { get; set; }
    
    public Kid(string name)
    {
        this.KidName = name;
        this.KidNumber = Interlocked.Increment(ref _counter);
    }
}

就像++unchecked 上下文中一样,它处理溢出的情况;一旦你点击int.MaxValue,if 将自动换行到int.MinValue。如果您不想要负 ID,则必须单独处理。

【讨论】:

    猜你喜欢
    • 2012-01-09
    • 2012-03-04
    • 2017-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-19
    • 2018-01-28
    相关资源
    最近更新 更多