创建C#方法以生成自动增量ID

时间:2018-08-01 20:23:37

标签: c#

我是编程新手,我想尝试创建一个返回自动增量id的函数,但是该代码无法正常工作,即使没有得到什么,我也肯定有一些缺失。 这里的代码是要创建一个每次都被调用的函数,它会创建一个自动增量id,就像在SQL(主键)上一样:

class Program
{
    static void Main(string[] args)
    {
        string[] dataInsert = new string[10];

        for(int i = 0; i < dataInsert.Length; i++)
        {
            dataInsert[i] = Convert.ToString(generateId());
        }

        for (int i = 0; i < dataInsert.Length; i++)
        {
            Console.WriteLine(dataInsert[i]);
        }

        Console.ReadKey();
    }
    static int generateId()
    {
        int id = 1;
        return id += 1;
    }
}

4 个答案:

答案 0 :(得分:4)

更改

static int generateId()
{
    int id = 1;   //This resets the value to 1 every time you enter.
    return id+= 1;
}

收件人:

private static int id = 1;
static int generateId()
{
    return id++;
}

您的generateId将始终返回2,因为您将传递每次输入时都初始化为1的本地值。以我的示例为例,当应用运行时,Id将设置为1,然后递增。不过,它将始终从1开始。

添加对局部变量,字段变量和静态变量的说明。

像定义变量一样定义局部变量时,它仅存在于方法范围内,并且每次调用该方法时都会重新初始化。

您还可以定义只要存在对象实例就将存在的字段变量。例如:

public class AutoIncrment
{
    private int id = 1;
    public int GenerateId()
    {
       return id++;
    }
}

您可以像这样使用它:

var idState = new AutoIncrement();

console.WriteLine(idState.GenerateId()); // Outputs 1
console.WriteLine(idState.GenerateId()); // Outputs 2 
console.WriteLine(idState.GenerateId()); // Outputs 3 
console.WriteLine(idState.GenerateId()); // Outputs 4 .. And so on

var idState2 = new AutoIncrement();  // Create a new instance and it starts over

console.WriteLine(idState2.GenerateId()); // Outputs 1
console.WriteLine(idState2.GenerateId()); // Outputs 2 .. And so on
// Go back to idState object and it will keep going from where you last left off
console.WriteLine(idState.GenerateId()); // Outputs 5 

然后有一些静态变量,例如在顶部的答案中。它们作为类本身的一部分存在。由于该类在程序运行时始终存在,因此变量也存在于内存中。

答案 1 :(得分:3)

您可以制作一个static整数来记住先前返回的ID,然后使用Interlocked.Increment()根据需要将其递增:

using System.Threading;


class Program
{
    static int lastId = 0;

    static int generateId()
    {
        return Interlocked.Increment(ref lastId);
    }

    // Remainder of Program unchanged
}

Interlocked.Increment 递增指定变量并将其存储为原子操作,并返回递增值。它保证了从不同线程调用generateId()时不会返回重复的ID。

请注意文档中的以下remark

  

此方法通过包装以下内容来处理溢出情况:if location = Int32.MaxValuelocation + 1 = Int32.MinValue。没有异常。

因此,您可能想向generateId()添加逻辑以检查此内容并引发异常。

有关静态字段及其使用时间的更多信息,请参见:

更新

在评论中,提出以下问题:如果我们不知道有多个线程(即假设这是一个单线程应用程序),为什么这里Interlocked.Increment是必要的?

此时,应该始终假定应用是多线程的。如果有一种简单的线程安全模式替代方法,而无需花费大量额外成本(无论是开发成本还是运行时性能),都可以使用线程不安全模式,例如此处所示。由于OP自称为马德拉大学的学生,因此即使编写控制台应用程序,他们也应该开始学习线程安全模式,这样他们就不必取消学习线程不安全的知识技术。

答案 2 :(得分:0)

只需将您的int设为静态。

也可以在类空间中声明。不在函数中。

答案 3 :(得分:0)

您的代码始终以2方法重新调整generateid()

       static int id =1;
       for(int i=0;i<dataInsert.Length;i++)
        {
            dataInsert[i] = Convert.ToString(generateId());
        }

        static int generateId()
        {

          return id+= 1;
        }